Progress towards a managed object API
							parent
							
								
									0f23470717
								
							
						
					
					
						commit
						ace76a2d3f
					
				|  | @ -609,8 +609,6 @@ STRUCT Buffer_Summary{ | ||||||
|     bool32 unwrapped_lines; |     bool32 unwrapped_lines; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| GLOBAL_VAR Buffer_Summary null_buffer_summary = {0}; |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
| DOC(A markers is a location in a buffer that, once placed, is effected by edits the same way characters are effected.  In particular if an edit occurs in a location in the buffer before a marker, the marker is shifted forward or backward so that it remains on the same character.) | DOC(A markers is a location in a buffer that, once placed, is effected by edits the same way characters are effected.  In particular if an edit occurs in a location in the buffer before a marker, the marker is shifted forward or backward so that it remains on the same character.) | ||||||
| DOC_SEE(buffer_add_markers) | DOC_SEE(buffer_add_markers) | ||||||
|  | @ -622,15 +620,6 @@ STRUCT Marker{ | ||||||
|     bool32 lean_right; |     bool32 lean_right; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
| DOC(A handle to an internally held array of markers.) |  | ||||||
| DOC_SEE(Marker) |  | ||||||
| DOC_SEE(buffer_add_markers) |  | ||||||
| */ |  | ||||||
| TYPEDEF void* Marker_Handle; |  | ||||||
| 
 |  | ||||||
| TYPEDEF void Marker_Delete_Callback(struct Application_Links *app, Marker_Handle handle, void *user_data, uint32_t user_data_size); |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
| DOC(A four corner axis aligned rectangle, with integer coordinates.) | DOC(A four corner axis aligned rectangle, with integer coordinates.) | ||||||
| */ | */ | ||||||
|  | @ -702,6 +691,8 @@ STRUCT Query_Bar{ | ||||||
| TYPEDEF int32_t Managed_Variable_ID; | TYPEDEF int32_t Managed_Variable_ID; | ||||||
| static Managed_Variable_ID ManagedVariableIndex_ERROR = -1; | static Managed_Variable_ID ManagedVariableIndex_ERROR = -1; | ||||||
| 
 | 
 | ||||||
|  | TYPEDEF uint64_t Managed_Object; | ||||||
|  | 
 | ||||||
| ENUM(int32_t, Dynamic_Scope_Type){ | ENUM(int32_t, Dynamic_Scope_Type){ | ||||||
|     DynamicScopeType_Global = 0, |     DynamicScopeType_Global = 0, | ||||||
|     DynamicScopeType_Intersected = 1, |     DynamicScopeType_Intersected = 1, | ||||||
|  |  | ||||||
|  | @ -18,13 +18,13 @@ write_character_parameter(Application_Links *app, uint8_t *character, uint32_t l | ||||||
|         next_cursor_marker.pos = character_pos_to_pos(app, &view, &buffer, view.cursor.character_pos); |         next_cursor_marker.pos = character_pos_to_pos(app, &view, &buffer, view.cursor.character_pos); | ||||||
|         next_cursor_marker.lean_right = true; |         next_cursor_marker.lean_right = true; | ||||||
|          |          | ||||||
|         Marker_Handle handle = buffer_add_markers(app, &buffer, 1, 0, 0, 0); |         Managed_Object handle = buffer_add_markers(app, buffer.buffer_id, 1, 0); | ||||||
|         buffer_set_markers(app, &buffer, handle, 0, 1, &next_cursor_marker); |         buffer_set_markers(app, handle, 0, 1, &next_cursor_marker); | ||||||
|          |          | ||||||
|         buffer_replace_range(app, &buffer, pos, pos, (char*)character, length); |         buffer_replace_range(app, &buffer, pos, pos, (char*)character, length); | ||||||
|          |          | ||||||
|         buffer_get_markers(app, &buffer, handle, 0, 1, &next_cursor_marker); |         buffer_get_markers(app, handle, 0, 1, &next_cursor_marker); | ||||||
|         buffer_remove_markers(app, &buffer, handle); |         buffer_remove_markers(app, handle); | ||||||
|          |          | ||||||
|         view_set_cursor(app, &view, seek_pos(next_cursor_marker.pos), true); |         view_set_cursor(app, &view, seek_pos(next_cursor_marker.pos), true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -17,12 +17,11 @@ struct Application_Links; | ||||||
| #define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len) | #define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len) | ||||||
| #define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out) | #define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out) | ||||||
| #define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type) | #define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type) | ||||||
| #define BUFFER_ADD_MARKERS_SIG(n) Marker_Handle n(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size) | #define BUFFER_ADD_MARKERS_SIG(n) Managed_Object n(Application_Links *app, Buffer_ID buffer_id, uint32_t marker_count, Dynamic_Scope *scope) | ||||||
| #define GET_BUFFER_BY_MARKER_HANDLE_SIG(n) Buffer_Summary n(Application_Links *app, Marker_Handle marker, Access_Flag access) | #define GET_BUFFER_BY_MARKER_HANDLE_SIG(n) Buffer_Summary n(Application_Links *app, Managed_Object marker_object, Access_Flag access) | ||||||
| #define GET_USER_DATA_BY_MARKER_HANDLE_SIG(n) Data n(Application_Links *app, Marker_Handle marker) | #define BUFFER_SET_MARKERS_SIG(n) bool32 n(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers) | ||||||
| #define BUFFER_SET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers) | #define BUFFER_GET_MARKERS_SIG(n) bool32 n(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out) | ||||||
| #define BUFFER_GET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out) | #define BUFFER_REMOVE_MARKERS_SIG(n) bool32 n(Application_Links *app, Managed_Object marker) | ||||||
| #define BUFFER_REMOVE_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker) |  | ||||||
| #define BUFFER_GET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out) | #define BUFFER_GET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out) | ||||||
| #define BUFFER_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value) | #define BUFFER_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value) | ||||||
| #define BUFFER_GET_DYNAMIC_SCOPE_SIG(n) Dynamic_Scope n(Application_Links *app, Buffer_ID buffer_id) | #define BUFFER_GET_DYNAMIC_SCOPE_SIG(n) Dynamic_Scope n(Application_Links *app, Buffer_ID buffer_id) | ||||||
|  | @ -121,7 +120,6 @@ typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function); | ||||||
| typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function); | typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function); | ||||||
| typedef BUFFER_ADD_MARKERS_SIG(Buffer_Add_Markers_Function); | typedef BUFFER_ADD_MARKERS_SIG(Buffer_Add_Markers_Function); | ||||||
| typedef GET_BUFFER_BY_MARKER_HANDLE_SIG(Get_Buffer_By_Marker_Handle_Function); | typedef GET_BUFFER_BY_MARKER_HANDLE_SIG(Get_Buffer_By_Marker_Handle_Function); | ||||||
| typedef GET_USER_DATA_BY_MARKER_HANDLE_SIG(Get_User_Data_By_Marker_Handle_Function); |  | ||||||
| typedef BUFFER_SET_MARKERS_SIG(Buffer_Set_Markers_Function); | typedef BUFFER_SET_MARKERS_SIG(Buffer_Set_Markers_Function); | ||||||
| typedef BUFFER_GET_MARKERS_SIG(Buffer_Get_Markers_Function); | typedef BUFFER_GET_MARKERS_SIG(Buffer_Get_Markers_Function); | ||||||
| typedef BUFFER_REMOVE_MARKERS_SIG(Buffer_Remove_Markers_Function); | typedef BUFFER_REMOVE_MARKERS_SIG(Buffer_Remove_Markers_Function); | ||||||
|  | @ -225,7 +223,6 @@ Buffer_Compute_Cursor_Function *buffer_compute_cursor; | ||||||
| Buffer_Batch_Edit_Function *buffer_batch_edit; | Buffer_Batch_Edit_Function *buffer_batch_edit; | ||||||
| Buffer_Add_Markers_Function *buffer_add_markers; | Buffer_Add_Markers_Function *buffer_add_markers; | ||||||
| Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle; | Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle; | ||||||
| Get_User_Data_By_Marker_Handle_Function *get_user_data_by_marker_handle; |  | ||||||
| Buffer_Set_Markers_Function *buffer_set_markers; | Buffer_Set_Markers_Function *buffer_set_markers; | ||||||
| Buffer_Get_Markers_Function *buffer_get_markers; | Buffer_Get_Markers_Function *buffer_get_markers; | ||||||
| Buffer_Remove_Markers_Function *buffer_remove_markers; | Buffer_Remove_Markers_Function *buffer_remove_markers; | ||||||
|  | @ -328,7 +325,6 @@ Buffer_Compute_Cursor_Function *buffer_compute_cursor_; | ||||||
| Buffer_Batch_Edit_Function *buffer_batch_edit_; | Buffer_Batch_Edit_Function *buffer_batch_edit_; | ||||||
| Buffer_Add_Markers_Function *buffer_add_markers_; | Buffer_Add_Markers_Function *buffer_add_markers_; | ||||||
| Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle_; | Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle_; | ||||||
| Get_User_Data_By_Marker_Handle_Function *get_user_data_by_marker_handle_; |  | ||||||
| Buffer_Set_Markers_Function *buffer_set_markers_; | Buffer_Set_Markers_Function *buffer_set_markers_; | ||||||
| Buffer_Get_Markers_Function *buffer_get_markers_; | Buffer_Get_Markers_Function *buffer_get_markers_; | ||||||
| Buffer_Remove_Markers_Function *buffer_remove_markers_; | Buffer_Remove_Markers_Function *buffer_remove_markers_; | ||||||
|  | @ -439,7 +435,6 @@ app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\ | ||||||
| app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\ | app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\ | ||||||
| app_links->buffer_add_markers_ = Buffer_Add_Markers;\ | app_links->buffer_add_markers_ = Buffer_Add_Markers;\ | ||||||
| app_links->get_buffer_by_marker_handle_ = Get_Buffer_By_Marker_Handle;\ | app_links->get_buffer_by_marker_handle_ = Get_Buffer_By_Marker_Handle;\ | ||||||
| app_links->get_user_data_by_marker_handle_ = Get_User_Data_By_Marker_Handle;\ |  | ||||||
| app_links->buffer_set_markers_ = Buffer_Set_Markers;\ | app_links->buffer_set_markers_ = Buffer_Set_Markers;\ | ||||||
| app_links->buffer_get_markers_ = Buffer_Get_Markers;\ | app_links->buffer_get_markers_ = Buffer_Get_Markers;\ | ||||||
| app_links->buffer_remove_markers_ = Buffer_Remove_Markers;\ | app_links->buffer_remove_markers_ = Buffer_Remove_Markers;\ | ||||||
|  | @ -540,12 +535,11 @@ static inline bool32 buffer_read_range(Application_Links *app, Buffer_Summary *b | ||||||
| static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range(app, buffer, start, end, str, len));} | static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range(app, buffer, start, end, str, len));} | ||||||
| static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer, seek, cursor_out));} | static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer, seek, cursor_out));} | ||||||
| static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit(app, buffer, str, str_len, edits, edit_count, type));} | static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit(app, buffer, str, str_len, edits, edit_count, type));} | ||||||
| static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size){return(app->buffer_add_markers(app, buffer, marker_count, callback, user_data, user_data_size));} | static inline Managed_Object buffer_add_markers(Application_Links *app, Buffer_ID buffer_id, uint32_t marker_count, Dynamic_Scope *scope){return(app->buffer_add_markers(app, buffer_id, marker_count, scope));} | ||||||
| static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle(app, marker, access));} | static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Managed_Object marker_object, Access_Flag access){return(app->get_buffer_by_marker_handle(app, marker_object, access));} | ||||||
| static inline Data get_user_data_by_marker_handle(Application_Links *app, Marker_Handle marker){return(app->get_user_data_by_marker_handle(app, marker));} | static inline bool32 buffer_set_markers(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers(app, marker_object, first_marker_index, marker_count, source_markers));} | ||||||
| static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers(app, buffer, marker, first_marker_index, marker_count, source_markers));} | static inline bool32 buffer_get_markers(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers(app, marker_object, first_marker_index, marker_count, markers_out));} | ||||||
| static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers(app, buffer, marker, first_marker_index, marker_count, markers_out));} | static inline bool32 buffer_remove_markers(Application_Links *app, Managed_Object marker){return(app->buffer_remove_markers(app, marker));} | ||||||
| static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers(app, buffer, marker));} |  | ||||||
| static inline bool32 buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out){return(app->buffer_get_setting(app, buffer, setting, value_out));} | static inline bool32 buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out){return(app->buffer_get_setting(app, buffer, setting, value_out));} | ||||||
| static inline bool32 buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value){return(app->buffer_set_setting(app, buffer, setting, value));} | static inline bool32 buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value){return(app->buffer_set_setting(app, buffer, setting, value));} | ||||||
| static inline Dynamic_Scope buffer_get_dynamic_scope(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_get_dynamic_scope(app, buffer_id));} | static inline Dynamic_Scope buffer_get_dynamic_scope(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_get_dynamic_scope(app, buffer_id));} | ||||||
|  | @ -643,12 +637,11 @@ static inline bool32 buffer_read_range(Application_Links *app, Buffer_Summary *b | ||||||
| static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range_(app, buffer, start, end, str, len));} | static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range_(app, buffer, start, end, str, len));} | ||||||
| static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer, seek, cursor_out));} | static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer, seek, cursor_out));} | ||||||
| static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit_(app, buffer, str, str_len, edits, edit_count, type));} | static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit_(app, buffer, str, str_len, edits, edit_count, type));} | ||||||
| static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size){return(app->buffer_add_markers_(app, buffer, marker_count, callback, user_data, user_data_size));} | static inline Managed_Object buffer_add_markers(Application_Links *app, Buffer_ID buffer_id, uint32_t marker_count, Dynamic_Scope *scope){return(app->buffer_add_markers_(app, buffer_id, marker_count, scope));} | ||||||
| static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle_(app, marker, access));} | static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Managed_Object marker_object, Access_Flag access){return(app->get_buffer_by_marker_handle_(app, marker_object, access));} | ||||||
| static inline Data get_user_data_by_marker_handle(Application_Links *app, Marker_Handle marker){return(app->get_user_data_by_marker_handle_(app, marker));} | static inline bool32 buffer_set_markers(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers_(app, marker_object, first_marker_index, marker_count, source_markers));} | ||||||
| static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers_(app, buffer, marker, first_marker_index, marker_count, source_markers));} | static inline bool32 buffer_get_markers(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers_(app, marker_object, first_marker_index, marker_count, markers_out));} | ||||||
| static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers_(app, buffer, marker, first_marker_index, marker_count, markers_out));} | static inline bool32 buffer_remove_markers(Application_Links *app, Managed_Object marker){return(app->buffer_remove_markers_(app, marker));} | ||||||
| static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers_(app, buffer, marker));} |  | ||||||
| static inline bool32 buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out){return(app->buffer_get_setting_(app, buffer, setting, value_out));} | static inline bool32 buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out){return(app->buffer_get_setting_(app, buffer, setting, value_out));} | ||||||
| static inline bool32 buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value){return(app->buffer_set_setting_(app, buffer, setting, value));} | static inline bool32 buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value){return(app->buffer_set_setting_(app, buffer, setting, value));} | ||||||
| static inline Dynamic_Scope buffer_get_dynamic_scope(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_get_dynamic_scope_(app, buffer_id));} | static inline Dynamic_Scope buffer_get_dynamic_scope(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_get_dynamic_scope_(app, buffer_id));} | ||||||
|  |  | ||||||
|  | @ -263,21 +263,21 @@ static Command_Metadata fcoder_metacmd_table[202] = { | ||||||
| { PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22,  "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 30, 1168 }, | { PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22,  "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 30, 1168 }, | ||||||
| { PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16,  "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 30, 1175 }, | { PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16,  "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 30, 1175 }, | ||||||
| { PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22,  "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 84 }, | { PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22,  "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 84 }, | ||||||
| { PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33,  "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 571 }, | { PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33,  "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 532 }, | ||||||
| { PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22,  "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 553 }, | { PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22,  "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 514 }, | ||||||
| { PROC_LINKS(goto_jump_at_cursor_direct, 0), "goto_jump_at_cursor_direct", 26,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 8 }, | { PROC_LINKS(goto_jump_at_cursor_direct, 0), "goto_jump_at_cursor_direct", 26,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 8 }, | ||||||
| { PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list..", 168, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 29 }, | { PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list..", 168, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 29 }, | ||||||
| { PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 399 }, | { PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 360 }, | ||||||
| { PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 371 }, | { PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26,  "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 332 }, | ||||||
| { PROC_LINKS(goto_line, 0), "goto_line", 9,  "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 585 }, | { PROC_LINKS(goto_line, 0), "goto_line", 9,  "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 585 }, | ||||||
| { PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 48 }, | { PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 48 }, | ||||||
| { PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 66 }, | { PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 66 }, | ||||||
| { PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 522 }, | { PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 483 }, | ||||||
| { PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 492 }, | { PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21,  "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 453 }, | ||||||
| { PROC_LINKS(goto_prev_jump_direct, 0), "goto_prev_jump_direct", 21,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 57 }, | { PROC_LINKS(goto_prev_jump_direct, 0), "goto_prev_jump_direct", 21,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 57 }, | ||||||
| { PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 75 }, | { PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 75 }, | ||||||
| { PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 538 }, | { PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 499 }, | ||||||
| { PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 508 }, | { PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21,  "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 469 }, | ||||||
| { PROC_LINKS(hide_filebar, 0), "hide_filebar", 12,  "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 471 }, | { PROC_LINKS(hide_filebar, 0), "hide_filebar", 12,  "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 471 }, | ||||||
| { PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14,  "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 457 }, | { PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14,  "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 457 }, | ||||||
| { PROC_LINKS(highlight_next_scope_absolute, 0), "highlight_next_scope_absolute", 29,  "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\4coder_scope_commands.cpp", 40, 363 }, | { PROC_LINKS(highlight_next_scope_absolute, 0), "highlight_next_scope_absolute", 29,  "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\4coder_scope_commands.cpp", 40, 363 }, | ||||||
|  | @ -334,8 +334,8 @@ static Command_Metadata fcoder_metacmd_table[202] = { | ||||||
| { PROC_LINKS(move_up_10, 0), "move_up_10", 10,  "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 256 }, | { PROC_LINKS(move_up_10, 0), "move_up_10", 10,  "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 39, 256 }, | ||||||
| { PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 101 }, | { PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 101 }, | ||||||
| { PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 116 }, | { PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_direct.cpp", 37, 116 }, | ||||||
| { PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 609 }, | { PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 570 }, | ||||||
| { PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 594 }, | { PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31,  "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 555 }, | ||||||
| { PROC_LINKS(open_all_code, 0), "open_all_code", 13,  "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 42, 1055 }, | { PROC_LINKS(open_all_code, 0), "open_all_code", 13,  "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 42, 1055 }, | ||||||
| { PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23,  "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 42, 1062 }, | { PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23,  "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 42, 1062 }, | ||||||
| { PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18,  "Opens the 4coder theme selector list.", 37, "w:\\4ed\\code\\4coder_lists.cpp", 31, 792 }, | { PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18,  "Opens the 4coder theme selector list.", 37, "w:\\4ed\\code\\4coder_lists.cpp", 31, 792 }, | ||||||
|  |  | ||||||
|  | @ -38,55 +38,6 @@ binary_search(uint32_t *array, int32_t stride, int32_t count, uint32_t x){ | ||||||
|     return(i); |     return(i); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static Sticky_Jump_Destination_Array |  | ||||||
| make_sticky_jump_destination_array(uint32_t first_jump_index, Marker_Handle handle){ |  | ||||||
|     Sticky_Jump_Destination_Array r; |  | ||||||
|     r.first_jump_index = first_jump_index; |  | ||||||
|     r.handle = handle; |  | ||||||
|     return(r); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static Sticky_Jump_Source |  | ||||||
| make_sticky_jump_source(uint32_t line_number, uint32_t flags){ |  | ||||||
|     Sticky_Jump_Source r; |  | ||||||
|     r.line_number = line_number; |  | ||||||
|     r.flags = flags; |  | ||||||
|     return(r); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void |  | ||||||
| double_dst_max(General_Memory *general, Marker_List *list){ |  | ||||||
|     uint32_t new_dst_max = list->dst_max*2; |  | ||||||
|     list->dst = gen_realloc_array(general, Sticky_Jump_Destination_Array, list->dst, list->dst_max, new_dst_max); |  | ||||||
|     list->dst_max = new_dst_max; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void |  | ||||||
| double_jump_max(General_Memory *general, Marker_List *list){ |  | ||||||
|     uint32_t new_jump_max = list->jump_max*2; |  | ||||||
|     list->jumps = gen_realloc_array(general, Sticky_Jump_Source, list->jumps, list->jump_max, new_jump_max); |  | ||||||
|     list->jump_max = new_jump_max; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void |  | ||||||
| marker_list_remove_references(Marker_List *list, Marker_Handle handle){ |  | ||||||
|     int32_t count = list->dst_count; |  | ||||||
|     Sticky_Jump_Destination_Array *dst = list->dst; |  | ||||||
|     for (int32_t i = 0; i < count; ++i, ++dst){ |  | ||||||
|         if (dst->handle == handle){ |  | ||||||
|             dst->handle = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void |  | ||||||
| sticky_jump_markers_cleanup(Application_Links *app, Marker_Handle handle, void *user_data, uint32_t user_data_size){ |  | ||||||
|     if (user_data_size == sizeof(Marker_List*)){ |  | ||||||
|         Marker_List *list = *(Marker_List**)user_data; |  | ||||||
|         marker_list_remove_references(list, handle); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static Sticky_Jump_Array | static Sticky_Jump_Array | ||||||
| parse_buffer_to_jump_array(Application_Links *app, Partition *arena, Buffer_Summary buffer){ | parse_buffer_to_jump_array(Application_Links *app, Partition *arena, Buffer_Summary buffer){ | ||||||
|     Sticky_Jump_Array result = {0}; |     Sticky_Jump_Array result = {0}; | ||||||
|  | @ -176,7 +127,7 @@ init_marker_list(Application_Links *app, Partition *part, General_Memory *genera | ||||||
|     Dynamic_Scope scope_array[2]; |     Dynamic_Scope scope_array[2]; | ||||||
|     scope_array[0] = buffer_get_dynamic_scope(app, buffer_id); |     scope_array[0] = buffer_get_dynamic_scope(app, buffer_id); | ||||||
|      |      | ||||||
|     List_Node_Handle list_sentinel = managed_list_node_alloc(app, scope_array[0]); |     Managed_Object list_sentinel = managed_list_node_alloc(app, scope_array[0]); | ||||||
|      |      | ||||||
|     for (int32_t i = 0; i < buffer_ranges.count; i += 1){ |     for (int32_t i = 0; i < buffer_ranges.count; i += 1){ | ||||||
|         Range range = buffer_ranges.ranges[i]; |         Range range = buffer_ranges.ranges[i]; | ||||||
|  | @ -186,18 +137,18 @@ init_marker_list(Application_Links *app, Partition *part, General_Memory *genera | ||||||
|         scope_array[1] = buffer_get_dynamic_scope(app, target_buffer_id); |         scope_array[1] = buffer_get_dynamic_scope(app, target_buffer_id); | ||||||
|         Dynamic_Scope scope = get_intersected_dynamic_scope(app, scope_array, ArrayCount(scope_array)); |         Dynamic_Scope scope = get_intersected_dynamic_scope(app, scope_array, ArrayCount(scope_array)); | ||||||
|          |          | ||||||
|         Marker_Handle marker_handle = buffer_add_markers(app, target_buffer_id, jump_count, &scope); |         Managed_Object marker_handle = buffer_add_markers(app, target_buffer_id, jump_count, &scope); | ||||||
|         Temp_Memory marker_temp = begin_temp_memory(part); |         Temp_Memory marker_temp = begin_temp_memory(part); | ||||||
|         Marker *markers = push_array(part, Marker, jump_count); |         Marker *markers = push_array(part, Marker, jump_count); | ||||||
|         for (int32_t j = 0; j < jump_count; j += 1){ |         for (int32_t j = 0; j < jump_count; j += 1){ | ||||||
|             markers[j].pos = jumps.jumps[j + range.first].jump_pos; |             markers[j].pos = jumps.jumps[j + range.first].jump_pos; | ||||||
|             markers[j].lean_right = false; |             markers[j].lean_right = false; | ||||||
|         } |         } | ||||||
|         buffer_set_markers(app, handle, 0, jump_count, markers); |         buffer_set_markers(app, marker_handle, 0, jump_count, markers); | ||||||
|         end_temp_memory(marker_temp); |         end_temp_memory(marker_temp); | ||||||
|          |          | ||||||
|         int32_t line_details_mem_size = sizeof(Sticky_Jump_Line_Details)*jump_count; |         int32_t line_details_mem_size = sizeof(Sticky_Jump_Line_Details)*jump_count; | ||||||
|         Memory_Handle memory = managed_memory_alloc(app, scope, line_details_mem_size); |         Managed_Object memory = managed_memory_alloc(app, scope, line_details_mem_size); | ||||||
|         Temp_Memory details_temp = begin_temp_memory(part); |         Temp_Memory details_temp = begin_temp_memory(part); | ||||||
|         Sticky_Jump_Line_Details *details = push_array(part, Sticky_Jump_Line_Details, jump_count); |         Sticky_Jump_Line_Details *details = push_array(part, Sticky_Jump_Line_Details, jump_count); | ||||||
|         for (int32_t j = 0; j < jump_count; j += 1){ |         for (int32_t j = 0; j < jump_count; j += 1){ | ||||||
|  | @ -208,12 +159,12 @@ init_marker_list(Application_Links *app, Partition *part, General_Memory *genera | ||||||
|         managed_memory_set(app, memory, 0, details, line_details_mem_size); |         managed_memory_set(app, memory, 0, details, line_details_mem_size); | ||||||
|         end_temp_memory(details_temp); |         end_temp_memory(details_temp); | ||||||
|          |          | ||||||
|         List_Node_Handle node_handle = managed_list_node_alloc(app, scope, sizeof(Sticky_Jump_Node_Header)); |         Managed_Object node_handle = managed_list_node_alloc(app, scope, sizeof(Sticky_Jump_Node_Header)); | ||||||
|         managed_list_node_insert(app, list_sentinel, node_handle, ListInsert_Back); |         managed_list_node_insert(app, list_sentinel, node_handle, ListInsert_Back); | ||||||
|         Sticky_Jump_Node_Header node_header = {0}; |         Sticky_Jump_Node_Header node_header = {0}; | ||||||
|         node_header.memory = memory; |         node_header.memory = memory; | ||||||
|         node_header.markers = marker_handle; |         node_header.markers = marker_handle; | ||||||
|         node_handle.count = jump_count; |         node_header.count = jump_count; | ||||||
|         managed_memory_set(app, node_handle, 0, &node_header, sizeof(node_header)); |         managed_memory_set(app, node_handle, 0, &node_header, sizeof(node_header)); | ||||||
|     } |     } | ||||||
|     end_temp_memory(temp); |     end_temp_memory(temp); | ||||||
|  | @ -282,12 +233,6 @@ init_marker_list(Application_Links *app, Partition *part, General_Memory *genera | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| static void |  | ||||||
| free_marker_list(General_Memory *general, Marker_List list){ |  | ||||||
|     general_memory_free(general, list.dst); |  | ||||||
|     general_memory_free(general, list.jumps); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void | static void | ||||||
| delete_marker_list(Marker_List_Node *node){ | delete_marker_list(Marker_List_Node *node){ | ||||||
|     zdll_remove(marker_list_first, marker_list_last, node); |     zdll_remove(marker_list_first, marker_list_last, node); | ||||||
|  |  | ||||||
|  | @ -27,8 +27,8 @@ struct Sticky_Jump_Array{ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Sticky_Jump_Node_Header{ | struct Sticky_Jump_Node_Header{ | ||||||
|     Memory_Handle memory; |     Managed_Object memory; | ||||||
|     Marker_Handle markers; |     Managed_Object markers; | ||||||
|     int32_t first_index; |     int32_t first_index; | ||||||
|     int32_t count; |     int32_t count; | ||||||
| }; | }; | ||||||
|  | @ -37,25 +37,7 @@ enum Jump_Location_Flag{ | ||||||
|     JumpFlag_IsSubJump = 0x1, |     JumpFlag_IsSubJump = 0x1, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Sticky_Jump_Destination_Array{ |  | ||||||
|     uint32_t first_jump_index; |  | ||||||
|     Marker_Handle handle; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct Sticky_Jump_Source{ |  | ||||||
|     uint32_t line_number; |  | ||||||
|     uint32_t flags; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct Marker_List{ | struct Marker_List{ | ||||||
|     Sticky_Jump_Destination_Array *dst; |  | ||||||
|     int32_t dst_count; |  | ||||||
|     int32_t dst_max; |  | ||||||
|      |  | ||||||
|     Sticky_Jump_Source *jumps; |  | ||||||
|     int32_t jump_count; |  | ||||||
|     int32_t jump_max; |  | ||||||
|      |  | ||||||
|     int32_t previous_size; |     int32_t previous_size; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -788,65 +788,46 @@ DOC_SEE(Buffer_Batch_Edit_Type) | ||||||
|     return(result); |     return(result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| API_EXPORT Marker_Handle | API_EXPORT Managed_Object | ||||||
| Buffer_Add_Markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size) | Buffer_Add_Markers(Application_Links *app, Buffer_ID buffer_id, uint32_t marker_count, Dynamic_Scope *scope) | ||||||
| /*
 | /*
 | ||||||
| DOC_PARAM(buffer, The buffer on which to add the new markers.) | DOC_PARAM(buffer_id, The id of the buffer on which to add the new markers.) | ||||||
| DOC_PARAM(marker_count, How many markers to be stored in the new marker array.) | DOC_PARAM(marker_count, How many markers to be stored in the new marker array.) | ||||||
| DOC_PARAM(callback, A callback that will be called if the buffer closes with these markers still attached.) | DOC_PARAM(scope, Optional dynamic scope tied to the marker's lifetime.  Note this scope will be implicitly interesected with the scope tied to the target buffer.) | ||||||
| DOC_PARAM(user_data, A pointer to data that will be passed to the callback on close.  The data will be copied so you do not need to manage it's lifetime.) |  | ||||||
| DOC_PARAM(user_data_size, The size of the data pointed to by user_data in bytes.) |  | ||||||
| DOC_RETURN(If this call succeeds it returns a handle to the new markers.  If it fails it returns a null handle.) | DOC_RETURN(If this call succeeds it returns a handle to the new markers.  If it fails it returns a null handle.) | ||||||
| DOC(This call makes an allocation of markers for the specified buffer.  The newly allocated markers are not immediately activated.  To activate a marker use buffer_set_markers to give the marker a value.  The markers will remain allocated on the buffer until buffer_remove_markers is called or until the buffer is killed.) | DOC(This call makes an allocation of markers for the specified buffer.  The newly allocated markers are not immediately activated.  To activate a marker use buffer_set_markers to give the marker a value.  The markers will remain allocated on the buffer until buffer_remove_markers is called or until the buffer is killed.) | ||||||
| DOC_SEE(Marker) | DOC_SEE(Marker) | ||||||
| */{ | */{ | ||||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; |     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||||
|     Models *models = cmd->models; |     Models *models = cmd->models; | ||||||
|     Editing_File *file = imp_get_file(cmd, buffer); |     Editing_File *file = imp_get_file(cmd, buffer_id); | ||||||
|      |     Managed_Object result = 0; | ||||||
|     Marker_Handle result = 0; |  | ||||||
|     if (file != 0){ |     if (file != 0){ | ||||||
|         result = allocate_markers_state(&models->mem.general, file, marker_count, |         result = (Managed_Object)allocate_markers_state(&models->mem.general, file, marker_count); | ||||||
|                                         callback, user_data, user_data_size); |  | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     return(result); |     return(result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| API_EXPORT Buffer_Summary | API_EXPORT Buffer_Summary | ||||||
| Get_Buffer_By_Marker_Handle(Application_Links *app, Marker_Handle marker, Access_Flag access) | Get_Buffer_By_Marker_Handle(Application_Links *app, Managed_Object marker_object, Access_Flag access) | ||||||
| /*
 | /*
 | ||||||
| DOC_PARAM(marker, The marker handle to query.) | DOC_PARAM(marker_object, The marker handle to query.) | ||||||
| DOC_PARAM(access, The access parameter determines what levels of protection this call can access.) | DOC_PARAM(access, The access parameter determines what levels of protection this call can access.) | ||||||
| DOC_SEE(Marker) | DOC_SEE(Marker) | ||||||
| */{ | */{ | ||||||
|     Buffer_Summary buffer = {0}; |     Buffer_Summary buffer = {0}; | ||||||
|     if (marker != 0){ |     if (object != 0){ | ||||||
|         Buffer_ID buffer_id = get_buffer_id_from_marker_handle(marker); |         void *ptr = IntAsPtr(marker_object); | ||||||
|  |         Buffer_ID buffer_id = get_buffer_id_from_marker_handle(ptr); | ||||||
|         buffer = Get_Buffer(app, buffer_id, access); |         buffer = Get_Buffer(app, buffer_id, access); | ||||||
|     } |     } | ||||||
|     return(buffer); |     return(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| API_EXPORT Data |  | ||||||
| Get_User_Data_By_Marker_Handle(Application_Links *app, Marker_Handle marker) |  | ||||||
| /*
 |  | ||||||
| DOC_PARAM(marker, The marker thandle to query.) |  | ||||||
| DOC_RETURN(Returns a data struct containing the user data passed in to buffer_add_markers, or a zero struct if the handle is null.) |  | ||||||
| DOC_SEE(Marker) |  | ||||||
| */{ |  | ||||||
|     Data data = {0}; |  | ||||||
|     if (marker != 0){ |  | ||||||
|         data = get_user_data_from_marker_handle(marker); |  | ||||||
|     } |  | ||||||
|     return(data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| API_EXPORT bool32 | API_EXPORT bool32 | ||||||
| Buffer_Set_Markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers) | Buffer_Set_Markers(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers) | ||||||
| /*
 | /*
 | ||||||
| DOC_PARAM(buffer, The buffer on which the specified markers are attached.) | DOC_PARAM(marker_object, The marker handle refering to the markers to be set.) | ||||||
| DOC_PARAM(marker, The marker handle refering to the markers to be set.) |  | ||||||
| DOC_PARAM(first_marker_index, The index of the first marker to be set by this call.) | DOC_PARAM(first_marker_index, The index of the first marker to be set by this call.) | ||||||
| DOC_PARAM(marker_count, The number of markers to be set by this call.) | DOC_PARAM(marker_count, The number of markers to be set by this call.) | ||||||
| DOC_PARAM(source_markers, An array of marker_count Markers to specify the values to set to the markers specified.) | DOC_PARAM(source_markers, An array of marker_count Markers to specify the values to set to the markers specified.) | ||||||
|  | @ -855,23 +836,24 @@ DOC(This call sets the value of a Marker, eliminating whatever value was there b | ||||||
| DOC_SEE(Marker) | DOC_SEE(Marker) | ||||||
| */{ | */{ | ||||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; |     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||||
|     Editing_File *file = imp_get_file(cmd, buffer); |  | ||||||
|      |  | ||||||
|     bool32 result = false; |     bool32 result = false; | ||||||
|  |     if (marker_object != 0){ | ||||||
|  |         void *ptr = IntAsPtr(marker_object); | ||||||
|  |         Buffer_ID buffer_id = get_buffer_id_from_marker_handle(ptr); | ||||||
|  |         Editing_File *file = imp_get_file(cmd, buffer_id); | ||||||
|         if (file != 0){ |         if (file != 0){ | ||||||
|         if (markers_set(file, marker, first_marker_index, marker_count, source_markers)){ |             if (markers_set(file, ptr, first_marker_index, marker_count, source_markers)){ | ||||||
|                 result = true; |                 result = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|      |     } | ||||||
|     return(result); |     return(result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| API_EXPORT bool32 | API_EXPORT bool32 | ||||||
| Buffer_Get_Markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out) | Buffer_Get_Markers(Application_Links *app, Managed_Object marker_object, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out) | ||||||
| /*
 | /*
 | ||||||
| DOC_PARAM(buffer, The buffer on which the specified markers are attached.) | DOC_PARAM(marker_object, The marker handle refering to the markers to be read.) | ||||||
| DOC_PARAM(marker, The marker handle refering to the markers to be read.) |  | ||||||
| DOC_PARAM(first_marker_index, The index of the first marker to be read by this call.) | DOC_PARAM(first_marker_index, The index of the first marker to be read by this call.) | ||||||
| DOC_PARAM(marker_count, The number of markers to be read by this call.) | DOC_PARAM(marker_count, The number of markers to be read by this call.) | ||||||
| DOC_PARAM(markers_out, An array of marker_count Markers to be filled by the result of the read.) | DOC_PARAM(markers_out, An array of marker_count Markers to be filled by the result of the read.) | ||||||
|  | @ -880,20 +862,22 @@ DOC(When the range specified by first_marker_index and marker_count is a range o | ||||||
| DOC_SEE(Marker) | DOC_SEE(Marker) | ||||||
| */{ | */{ | ||||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; |     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||||
|     Editing_File *file = imp_get_file(cmd, buffer); |  | ||||||
|      |  | ||||||
|     bool32 result = false; |     bool32 result = false; | ||||||
|  |     if (marker_object != 0){ | ||||||
|  |         void *ptr = IntAsPtr(marker_object); | ||||||
|  |         Buffer_ID buffer_id = get_buffer_id_from_marker_handle(ptr); | ||||||
|  |         Editing_File *file = imp_get_file(cmd, buffer_id); | ||||||
|         if (file != 0){ |         if (file != 0){ | ||||||
|         if (markers_get(file, marker, first_marker_index, marker_count, markers_out)){ |             if (markers_get(file, ptr, first_marker_index, marker_count, markers_out)){ | ||||||
|                 result = true; |                 result = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|      |     } | ||||||
|     return(result); |     return(result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| API_EXPORT bool32 | API_EXPORT bool32 | ||||||
| Buffer_Remove_Markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker) | Buffer_Remove_Markers(Application_Links *app, Managed_Object marker) | ||||||
| /*
 | /*
 | ||||||
| DOC_PARAM(buffer, The buffer on which the specified markers are attached.) | DOC_PARAM(buffer, The buffer on which the specified markers are attached.) | ||||||
| DOC_PARAM(marker, The marker handle refering to the markers to be detached from the buffer.) | DOC_PARAM(marker, The marker handle refering to the markers to be detached from the buffer.) | ||||||
|  | @ -903,15 +887,17 @@ DOC_SEE(buffer_add_markers) | ||||||
| */{ | */{ | ||||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; |     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||||
|     Models *models = cmd->models; |     Models *models = cmd->models; | ||||||
|     Editing_File *file = imp_get_file(cmd, buffer); |  | ||||||
|      |  | ||||||
|     bool32 result = false; |     bool32 result = false; | ||||||
|  |     if (marker_object != 0){ | ||||||
|  |         void *ptr = IntAsPtr(marker_object); | ||||||
|  |         Buffer_ID buffer_id = get_buffer_id_from_marker_handle(ptr); | ||||||
|  |         Editing_File *file = imp_get_file(cmd, buffer_id); | ||||||
|         if (file != 0){ |         if (file != 0){ | ||||||
|         if (markers_free(&models->mem.general, file, marker)){ |             if (markers_free(&models->mem.general, file, ptr)){ | ||||||
|                 result = true; |                 result = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|      |     } | ||||||
|     return(result); |     return(result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2369,6 +2355,7 @@ Get_Intersected_Dynamic_Scope(Application_Links *app, Dynamic_Scope *intersected | ||||||
| { | { | ||||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; |     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||||
|     Models *models = cmd->models; |     Models *models = cmd->models; | ||||||
|  |     Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; | ||||||
|     Partition *scratch = &models->mem.part; |     Partition *scratch = &models->mem.part; | ||||||
|     Dynamic_Scope result = {0}; |     Dynamic_Scope result = {0}; | ||||||
|      |      | ||||||
|  | @ -2388,12 +2375,14 @@ Get_Intersected_Dynamic_Scope(Application_Links *app, Dynamic_Scope *intersected | ||||||
|             case DynamicScopeType_Intersected: |             case DynamicScopeType_Intersected: | ||||||
|             { |             { | ||||||
|                 Lifetime_Key *key = (Lifetime_Key*)IntAsPtr(handle.intersected_opaque_handle); |                 Lifetime_Key *key = (Lifetime_Key*)IntAsPtr(handle.intersected_opaque_handle); | ||||||
|  |                 if (lifetime_key_check(lifetime_allocator, key)){ | ||||||
|                     i32 member_count = key->count; |                     i32 member_count = key->count; | ||||||
|                     Lifetime_Object **key_member_ptr = key->members; |                     Lifetime_Object **key_member_ptr = key->members; | ||||||
|                     for (i32 j = 0; j < member_count; j += 1, key_member_ptr += 1){ |                     for (i32 j = 0; j < member_count; j += 1, key_member_ptr += 1){ | ||||||
|                         Lifetime_Object **new_object_ptr = push_array(scratch, Lifetime_Object*, 1); |                         Lifetime_Object **new_object_ptr = push_array(scratch, Lifetime_Object*, 1); | ||||||
|                         *new_object_ptr = *key_member_ptr; |                         *new_object_ptr = *key_member_ptr; | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|             }break; |             }break; | ||||||
|              |              | ||||||
|             case DynamicScopeType_Buffer: |             case DynamicScopeType_Buffer: | ||||||
|  | @ -2426,7 +2415,6 @@ Get_Intersected_Dynamic_Scope(Application_Links *app, Dynamic_Scope *intersected | ||||||
|         member_count = lifetime_sort_and_dedup_object_set(object_ptr_array, member_count); |         member_count = lifetime_sort_and_dedup_object_set(object_ptr_array, member_count); | ||||||
|          |          | ||||||
|         General_Memory *general = &models->mem.general; |         General_Memory *general = &models->mem.general; | ||||||
|         Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; |  | ||||||
|         Lifetime_Key *key = lifetime_get_or_create_intersection_key(general, lifetime_allocator, object_ptr_array, member_count); |         Lifetime_Key *key = lifetime_get_or_create_intersection_key(general, lifetime_allocator, object_ptr_array, member_count); | ||||||
|         result.type = DynamicScopeType_Intersected; |         result.type = DynamicScopeType_Intersected; | ||||||
|         result.intersected_opaque_handle = (u64)(PtrAsInt(key)); |         result.intersected_opaque_handle = (u64)(PtrAsInt(key)); | ||||||
|  | @ -2472,6 +2460,7 @@ Managed_Variable_Create_Or_Get_ID(Application_Links *app, char *null_terminated_ | ||||||
| internal bool32 | internal bool32 | ||||||
| get_dynamic_variable(Command_Data *cmd, Dynamic_Scope handle, int32_t location, uint64_t **ptr_out){ | get_dynamic_variable(Command_Data *cmd, Dynamic_Scope handle, int32_t location, uint64_t **ptr_out){ | ||||||
|     Models *models = cmd->models; |     Models *models = cmd->models; | ||||||
|  |     Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; | ||||||
|     General_Memory *general = &models->mem.general; |     General_Memory *general = &models->mem.general; | ||||||
|     Dynamic_Variable_Layout *layout = &models->variable_layout; |     Dynamic_Variable_Layout *layout = &models->variable_layout; | ||||||
|     Dynamic_Variable_Block *block = 0; |     Dynamic_Variable_Block *block = 0; | ||||||
|  | @ -2485,7 +2474,9 @@ get_dynamic_variable(Command_Data *cmd, Dynamic_Scope handle, int32_t location, | ||||||
|         case DynamicScopeType_Intersected: |         case DynamicScopeType_Intersected: | ||||||
|         { |         { | ||||||
|             Lifetime_Key *key = (Lifetime_Key*)IntAsPtr(handle.intersected_opaque_handle); |             Lifetime_Key *key = (Lifetime_Key*)IntAsPtr(handle.intersected_opaque_handle); | ||||||
|  |             if (lifetime_key_check(lifetime_allocator, key)){ | ||||||
|                 block = &key->dynamic_vars; |                 block = &key->dynamic_vars; | ||||||
|  |             } | ||||||
|         }break; |         }break; | ||||||
|          |          | ||||||
|         case DynamicScopeType_Buffer: |         case DynamicScopeType_Buffer: | ||||||
|  |  | ||||||
|  | @ -122,6 +122,125 @@ dynamic_variables_get_ptr(General_Memory *general, | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////
 | ////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
|  | internal u64 | ||||||
|  | ptr_check__hash(Lifetime_Key *key){ | ||||||
|  |     u64 x = (u64)(PtrAsInt(key)); | ||||||
|  |     return(x >> 3); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | internal b32 | ||||||
|  | ptr_check_table_check(Ptr_Check_Table *table, void *key){ | ||||||
|  |     u32 max = table->max; | ||||||
|  |     if (max > 0 && table->count > 0){ | ||||||
|  |         u64 hash = ptr_check_hash(key); | ||||||
|  |         u32 first_index = hash%max; | ||||||
|  |         u32 index = first_index; | ||||||
|  |         void *keys = table->keys; | ||||||
|  |         for (;;){ | ||||||
|  |             if (keys[index] == key){ | ||||||
|  |                 return(true); | ||||||
|  |             } | ||||||
|  |             else if (hashes[index] == LifetimeKeyHash_Empty){ | ||||||
|  |                 return(false); | ||||||
|  |             } | ||||||
|  |             index += 1; | ||||||
|  |             if (index == max){ | ||||||
|  |                 index = 0; | ||||||
|  |             } | ||||||
|  |             if (index == first_index){ | ||||||
|  |                 return(false); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return(false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | internal Ptr_Check_Table | ||||||
|  | ptr_check_table_copy(General_Memory *general, Ptr_Check_Table *table, u32 new_max); | ||||||
|  | 
 | ||||||
|  | internal void | ||||||
|  | ptr_check_table_insert(General_Memory *general, Ptr_Check_Table *table, void *key){ | ||||||
|  |     { | ||||||
|  |         u32 max = table->max; | ||||||
|  |         u32 count = table->count; | ||||||
|  |         if (max == 0 || (count + 1)*6 > max*5){ | ||||||
|  |             Assert(general != 0); | ||||||
|  |             Ptr_Check_Table new_table = ptr_check_table_copy(general, *table, max*2); | ||||||
|  |             general_memory_free(general, table->mem_ptr); | ||||||
|  |             *table = new_table; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     { | ||||||
|  |         u32 max = table->max; | ||||||
|  |         if (max > 0 && table->count > 0){ | ||||||
|  |             u64 hash = ptr_check_hash(key); | ||||||
|  |             u32 first_index = hash%max; | ||||||
|  |             u32 index = first_index; | ||||||
|  |             void **keys = table->keys; | ||||||
|  |             for (;;){ | ||||||
|  |                 if (keys[index] == 0 || keys[index] == (Lifetime_Key*)1){ | ||||||
|  |                     keys[index] = key; | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |                 index += 1; | ||||||
|  |                 if (index == max){ | ||||||
|  |                     index = 0; | ||||||
|  |                 } | ||||||
|  |                 if (index == first_index){ | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | internal void | ||||||
|  | ptr_check_table_erase(Ptr_Check_Table *table, Lifetime_Key *erase_key){ | ||||||
|  |     u32 max = table->max; | ||||||
|  |     if (max > 0 && table->count > 0){ | ||||||
|  |         u64 hash = ptr_check_hash(erase_key); | ||||||
|  |         u32 first_index = hash%max; | ||||||
|  |         u32 index = first_index; | ||||||
|  |         void **keys = table->keys; | ||||||
|  |         for (;;){ | ||||||
|  |             if (keys[index] == erase_key){ | ||||||
|  |                 keys[index] = 0; | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             else if (hashes[index] == LifetimeKeyHash_Empty){ | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             index += 1; | ||||||
|  |             if (index == max){ | ||||||
|  |                 index = 0; | ||||||
|  |             } | ||||||
|  |             if (index == first_index){ | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | internal Lifetime_Key_Check_Table | ||||||
|  | ptr_check_table_copy(General_Memory *general, Lifetime_Key_Check_Table *table, u32 new_max){ | ||||||
|  |     Lifetime_Key_Check_Table new_table = {0}; | ||||||
|  |     new_table.max = clamp_bottom(table.max, new_max); | ||||||
|  |     new_table.max = clamp_bottom(307, new_table.max); | ||||||
|  |     i32 item_size = sizeof(*new_table.keys); | ||||||
|  |     new_table.keys = (Lifetime_Key**)general_memory_allocate(general, item_size*new_table.max); | ||||||
|  |     memset(new_table.keys, 0, item_size*new_table.max); | ||||||
|  |     for (u32 i = 0; i < table.max; i += 1){ | ||||||
|  |         u64 k = (u64)(PtrAsInt(table.keys[i])); | ||||||
|  |         if (k > 1){ | ||||||
|  |             ptr_check_table_insert(0, &new_table, table.keys[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return(new_table); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ////////////////////////////////
 | ||||||
|  | 
 | ||||||
| internal u64 | internal u64 | ||||||
| lifetime__key_hash(Lifetime_Object **object_ptr_array, i32 count){ | lifetime__key_hash(Lifetime_Object **object_ptr_array, i32 count){ | ||||||
|     u64 hash = bit_1; |     u64 hash = bit_1; | ||||||
|  | @ -219,6 +338,7 @@ lifetime__key_table_erase(Lifetime_Key_Table *table, Lifetime_Key *erase_key){ | ||||||
|                 if (erase_key == key){ |                 if (erase_key == key){ | ||||||
|                     hashes[index] = LifetimeKeyHash_Deleted; |                     hashes[index] = LifetimeKeyHash_Deleted; | ||||||
|                     table->keys[index] = 0; |                     table->keys[index] = 0; | ||||||
|  |                     return; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             else if (hashes[index] == LifetimeKeyHash_Empty){ |             else if (hashes[index] == LifetimeKeyHash_Empty){ | ||||||
|  | @ -299,6 +419,7 @@ lifetime__free_key(General_Memory *general, Lifetime_Allocator *lifetime_allocat | ||||||
|      |      | ||||||
|     // Free
 |     // Free
 | ||||||
|     lifetime__key_table_erase(&lifetime_allocator->key_table, key); |     lifetime__key_table_erase(&lifetime_allocator->key_table, key); | ||||||
|  |     ptr_check_table_erase(&lifetime_allocator->key_check_table, key); | ||||||
|     general_memory_free(general, key->members); |     general_memory_free(general, key->members); | ||||||
|     zdll_push_back(lifetime_allocator->free_keys.first, lifetime_allocator->free_keys.last, key); |     zdll_push_back(lifetime_allocator->free_keys.first, lifetime_allocator->free_keys.last, key); | ||||||
| } | } | ||||||
|  | @ -475,9 +596,15 @@ lifetime_get_or_create_intersection_key(General_Memory *general, Lifetime_Alloca | ||||||
|     dynamic_variables_block_init(general, &new_key->dynamic_vars); |     dynamic_variables_block_init(general, &new_key->dynamic_vars); | ||||||
|      |      | ||||||
|     lifetime__key_table_insert(general, &lifetime_allocator->key_table, hash, new_key); |     lifetime__key_table_insert(general, &lifetime_allocator->key_table, hash, new_key); | ||||||
|  |     ptr_check_table_insert(general, &lifetime_allocator->key_check_table, new_key); | ||||||
|      |      | ||||||
|     return(new_key); |     return(new_key); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | internal b32 | ||||||
|  | lifetime_key_check(Lifetime_Allocator *lifetime_allocator, Lifetime_Key *key){ | ||||||
|  |     return(ptr_check_table_check(&lifetime_allocator->key_check_table, key)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // BOTTOM
 | // BOTTOM
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,6 +33,14 @@ struct Dynamic_Variable_Block{ | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////
 | ////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
|  | struct Ptr_Check_Table{ | ||||||
|  |     void **keys; | ||||||
|  |     u32 count; | ||||||
|  |     u32 max; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | ////////////////////////////////
 | ||||||
|  | 
 | ||||||
| global_const i32 lifetime_key_reference_per_node = 32; | global_const i32 lifetime_key_reference_per_node = 32; | ||||||
| 
 | 
 | ||||||
| struct Lifetime_Key_Ref_Node{ | struct Lifetime_Key_Ref_Node{ | ||||||
|  | @ -105,6 +113,12 @@ struct Lifetime_Allocator{ | ||||||
|     Lifetime_Object_List free_objects; |     Lifetime_Object_List free_objects; | ||||||
|     Lifetime_Key_List free_keys; |     Lifetime_Key_List free_keys; | ||||||
|     Lifetime_Key_Table key_table; |     Lifetime_Key_Table key_table; | ||||||
|  |     Lifetime_Ptr_Check_Table key_check_table; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct Lifetime_Key_With_Opaque_ID{ | ||||||
|  |     Lifetime_Key *key; | ||||||
|  |     u64 opaque_id; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								4ed_file.cpp
								
								
								
								
							
							
						
						
									
										14
									
								
								4ed_file.cpp
								
								
								
								
							|  | @ -45,23 +45,15 @@ clear_file_markers_state(Application_Links *app, General_Memory *general, Editin | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| internal void* | internal void* | ||||||
| allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max, | allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max){ | ||||||
|                        Marker_Delete_Callback *callback, void *user_data, u32 user_data_size){ |     u32 memory_size = sizeof(Marker_Array) + sizeof(Marker)*new_array_max; | ||||||
|     u32 rounded_user_data_size = l_round_up_u32(user_data_size, 8); |  | ||||||
|     u32 memory_size = sizeof(Marker_Array) + rounded_user_data_size + sizeof(Marker)*new_array_max; |  | ||||||
|     memory_size = l_round_up_u32(memory_size, KB(4)); |  | ||||||
|     u32 real_max = (memory_size - sizeof(Marker_Array) - rounded_user_data_size)/sizeof(Marker); |  | ||||||
|     Marker_Array *array = (Marker_Array*)general_memory_allocate(general, memory_size); |     Marker_Array *array = (Marker_Array*)general_memory_allocate(general, memory_size); | ||||||
|      |      | ||||||
|     dll_insert_back(&file->markers.sentinel, array); |     dll_insert_back(&file->markers.sentinel, array); | ||||||
|     array->buffer_id = file->id; |     array->buffer_id = file->id; | ||||||
|     array->count = 0; |     array->count = 0; | ||||||
|     array->sim_max = new_array_max; |     array->sim_max = new_array_max; | ||||||
|     array->max = real_max; |     array->max = new_array_max; | ||||||
|     array->callback = callback; |  | ||||||
|     array->user_data_size = user_data_size; |  | ||||||
|     array->rounded_user_data_size = rounded_user_data_size; |  | ||||||
|     memcpy(array + 1, user_data, user_data_size); |  | ||||||
|      |      | ||||||
|     ++file->markers.array_count; |     ++file->markers.array_count; | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -46,9 +46,6 @@ struct Marker_Array{ | ||||||
|     u32 count; |     u32 count; | ||||||
|     u32 sim_max; |     u32 sim_max; | ||||||
|     u32 max; |     u32 max; | ||||||
|     Marker_Delete_Callback *callback; |  | ||||||
|     u32 user_data_size; |  | ||||||
|     u32 rounded_user_data_size; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define MarkerArrayBase(a) (Marker*)((u8*)(a) + sizeof(Marker_Array) + ((Marker_Array*)(a))->rounded_user_data_size) | #define MarkerArrayBase(a) (Marker*)((u8*)(a) + sizeof(Marker_Array) + ((Marker_Array*)(a))->rounded_user_data_size) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster