New file change notification system
This commit is contained in:
parent
422d67c41f
commit
ac04842f97
101
4ed.cpp
101
4ed.cpp
|
@ -12,6 +12,24 @@
|
|||
#define DEFAULT_DISPLAY_WIDTH 672
|
||||
#define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 550
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
Mutex_Lock::Mutex_Lock(System_Functions *s, System_Mutex m){
|
||||
s->mutex_acquire(m);
|
||||
this->system = s;
|
||||
this->mutex = m;
|
||||
}
|
||||
|
||||
Mutex_Lock::~Mutex_Lock(){
|
||||
this->system->mutex_release(this->mutex);
|
||||
}
|
||||
|
||||
Mutex_Lock::operator System_Mutex(){
|
||||
return(this->mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal App_Coroutine_State
|
||||
get_state(Application_Links *app){
|
||||
App_Coroutine_State state = {};
|
||||
|
@ -732,15 +750,15 @@ make_arena_models(Models *models){
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
internal App_Vars*
|
||||
internal Models*
|
||||
app_setup_memory(System_Functions *system, Application_Memory *memory){
|
||||
Cursor cursor = make_cursor(memory->vars_memory, memory->vars_memory_size);
|
||||
App_Vars *vars = push_array_zero(&cursor, App_Vars, 1);
|
||||
vars->models.mem.arena = make_arena_system(system);
|
||||
vars->models.base_allocator = vars->models.mem.arena.base_allocator;
|
||||
heap_init(&vars->models.mem.heap);
|
||||
heap_extend(&vars->models.mem.heap, memory->target_memory, memory->target_memory_size);
|
||||
return(vars);
|
||||
Models *models = push_array_zero(&cursor, Models, 1);
|
||||
models->mem.arena = make_arena_system(system);
|
||||
models->base_allocator = models->mem.arena.base_allocator;
|
||||
heap_init(&models->mem.heap);
|
||||
heap_extend(&models->mem.heap, memory->target_memory, memory->target_memory_size);
|
||||
return(models);
|
||||
}
|
||||
|
||||
internal u32
|
||||
|
@ -822,21 +840,21 @@ launch_command_via_keycode(System_Functions *system, Models *models, View *view,
|
|||
|
||||
App_Read_Command_Line_Sig(app_read_command_line){
|
||||
i32 out_size = 0;
|
||||
App_Vars *vars = app_setup_memory(system, memory);
|
||||
App_Settings *settings = &vars->models.settings;
|
||||
Models *models = app_setup_memory(system, memory);
|
||||
App_Settings *settings = &models->settings;
|
||||
memset(settings, 0, sizeof(*settings));
|
||||
plat_settings->font_size = 16;
|
||||
if (argc > 1){
|
||||
init_command_line_settings(&vars->models.settings, plat_settings, argc, argv);
|
||||
init_command_line_settings(&models->settings, plat_settings, argc, argv);
|
||||
}
|
||||
*files = vars->models.settings.init_files;
|
||||
*file_count = &vars->models.settings.init_files_count;
|
||||
*files = models->settings.init_files;
|
||||
*file_count = &models->settings.init_files_count;
|
||||
return(out_size);
|
||||
}
|
||||
|
||||
App_Init_Sig(app_init){
|
||||
App_Vars *vars = (App_Vars*)memory->vars_memory;
|
||||
Models *models = &vars->models;
|
||||
Models *models = (Models*)memory->vars_memory;
|
||||
models->system = system;
|
||||
models->keep_playing = true;
|
||||
|
||||
app_links_init(system, &models->app_links, memory->user_memory, memory->user_memory_size);
|
||||
|
@ -893,7 +911,10 @@ App_Init_Sig(app_init){
|
|||
dynamic_workspace_init(&models->mem.heap, &models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace);
|
||||
|
||||
// NOTE(allen): file setup
|
||||
working_set_init(system, &models->working_set);
|
||||
working_set_init(models, &models->working_set);
|
||||
|
||||
Mutex_Lock file_order_lock(system, models->working_set.mutex);
|
||||
|
||||
models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH;
|
||||
models->working_set.default_minimum_base_display_width = DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH;
|
||||
|
||||
|
@ -929,10 +950,6 @@ App_Init_Sig(app_init){
|
|||
models->title_space = push_array(arena, char, models->title_capacity);
|
||||
block_copy(models->title_space, WINDOW_NAME, sizeof(WINDOW_NAME));
|
||||
|
||||
// NOTE(allen): init system context
|
||||
models->system = system;
|
||||
models->vars = vars;
|
||||
|
||||
// NOTE(allen): init baked in buffers
|
||||
File_Init init_files[] = {
|
||||
{ string_u8_litinit("*messages*"), &models->message_buffer, true , },
|
||||
|
@ -978,6 +995,8 @@ App_Init_Sig(app_init){
|
|||
App_Step_Sig(app_step){
|
||||
Models *models = (Models*)memory->vars_memory;
|
||||
|
||||
Mutex_Lock file_order_lock(system, models->working_set.mutex);
|
||||
|
||||
models->next_animate_delay = max_u32;
|
||||
models->animate_next_frame = false;
|
||||
|
||||
|
@ -996,50 +1015,6 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// NOTE(allen): check files are up to date
|
||||
{
|
||||
b32 mem_too_small = 0;
|
||||
i32 size = 0;
|
||||
i32 buffer_size = KB(32);
|
||||
|
||||
Arena *scratch = &models->mem.arena;
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
char *buffer = push_array(scratch, char, buffer_size);
|
||||
u32 unmark_top = 0;
|
||||
u32 unmark_max = Thousand(8);
|
||||
Editing_File **unmark = (Editing_File**)push_array(scratch, Editing_File*, unmark_max);
|
||||
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
for (;system->get_file_change(buffer, buffer_size, &mem_too_small, &size);){
|
||||
Assert(!mem_too_small);
|
||||
Editing_File_Name canon = {};
|
||||
if (get_canon_name(system, scratch, SCu8(buffer, size), &canon)){
|
||||
Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon));
|
||||
if (file != 0){
|
||||
if (file->state.ignore_behind_os == 0){
|
||||
file_add_dirty_flag(file, DirtyState_UnloadedChanges);
|
||||
}
|
||||
else if (file->state.ignore_behind_os == 1){
|
||||
file->state.ignore_behind_os = 2;
|
||||
unmark[unmark_top++] = file;
|
||||
if (unmark_top == unmark_max){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < unmark_top; ++i){
|
||||
unmark[i]->state.ignore_behind_os = 0;
|
||||
}
|
||||
|
||||
end_temp(temp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE(allen): reorganizing panels on screen
|
||||
Vec2_i32 prev_dim = layout_get_root_size(&models->layout);
|
||||
Vec2_i32 current_dim = V2i32(target->width, target->height);
|
||||
|
|
|
@ -35,6 +35,7 @@ enum App_State{
|
|||
};
|
||||
|
||||
struct Models{
|
||||
System_Functions *system;
|
||||
Base_Allocator *base_allocator;
|
||||
Mem_Options mem;
|
||||
|
||||
|
@ -121,10 +122,6 @@ struct Models{
|
|||
b32 animated_last_frame;
|
||||
u64 last_render_usecond_stamp;
|
||||
|
||||
// System Context
|
||||
System_Functions *system;
|
||||
struct App_Vars *vars;
|
||||
|
||||
// Event Context
|
||||
Application_Step_Input *input;
|
||||
Key_Event_Data key;
|
||||
|
@ -162,11 +159,6 @@ struct Consumption_Record{
|
|||
char consumer[32];
|
||||
};
|
||||
|
||||
// TODO(allen): GET RID OF IT!
|
||||
struct App_Vars{
|
||||
Models models;
|
||||
};
|
||||
|
||||
typedef i32 App_Coroutine_Purpose;
|
||||
enum{
|
||||
Co_View,
|
||||
|
@ -217,6 +209,16 @@ enum{
|
|||
AppCoroutineRequest_ModifyFace = 2,
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
struct Mutex_Lock{
|
||||
Mutex_Lock(System_Functions *system, System_Mutex mutex);
|
||||
~Mutex_Lock();
|
||||
operator System_Mutex();
|
||||
System_Functions *system;
|
||||
System_Mutex mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -94,13 +94,13 @@ file_set_unimportant(Editing_File *file, b32 val){
|
|||
if (val){
|
||||
file->state.dirty = DirtyState_UpToDate;
|
||||
}
|
||||
file->settings.unimportant = (b8)(val != false);
|
||||
file->settings.unimportant = (b8)(val);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_set_to_loading(Editing_File *file){
|
||||
memset(&file->state, 0, sizeof(file->state));
|
||||
memset(&file->settings, 0, sizeof(file->settings));
|
||||
block_zero_struct(&file->state);
|
||||
block_zero_struct(&file->settings);
|
||||
file->is_loading = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,17 +98,18 @@ struct Editing_File{
|
|||
Node main_chain_node;
|
||||
};
|
||||
Node touch_node;
|
||||
Node reloaded_node;
|
||||
Node edit_finished_mark_node;
|
||||
b32 edit_finished_marked;
|
||||
b32 is_loading;
|
||||
Buffer_ID id;
|
||||
Editing_File_Settings settings;
|
||||
b32 is_loading;
|
||||
Editing_File_State state;
|
||||
File_Attributes attributes;
|
||||
Lifetime_Object *lifetime_object;
|
||||
Editing_File_Name base_name;
|
||||
Editing_File_Name unique_name;
|
||||
Editing_File_Name canon;
|
||||
b32 edit_finished_marked;
|
||||
Node edit_finished_mark_node;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,12 @@ typedef Sys_Wake_Up_Timer_Set_Sig(System_Wake_Up_Timer_Set);
|
|||
#define Sys_Wake_Up_Timer_Check_Sig(name) u64 name(Plat_Handle handle)
|
||||
typedef Sys_Wake_Up_Timer_Check_Sig(System_Wake_Up_Timer_Check);
|
||||
|
||||
#define Sys_Signal_Step_Sig(name) void name(u32 code)
|
||||
typedef Sys_Signal_Step_Sig(System_Signal_Step);
|
||||
|
||||
#define Sys_Sleep_Sig(name) void name(u64 microseconds)
|
||||
typedef Sys_Sleep_Sig(System_Sleep);
|
||||
|
||||
// clipboard
|
||||
#define Sys_Post_Clipboard_Sig(name) void name(String_Const_u8 str)
|
||||
typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard);
|
||||
|
@ -179,6 +185,8 @@ struct System_Functions{
|
|||
System_Wake_Up_Timer_Create *wake_up_timer_create;
|
||||
System_Wake_Up_Timer_Release *wake_up_timer_release;
|
||||
System_Wake_Up_Timer_Set *wake_up_timer_set;
|
||||
System_Signal_Step *signal_step;
|
||||
System_Sleep *sleep;
|
||||
|
||||
// clipboard
|
||||
System_Post_Clipboard *post_clipboard;
|
||||
|
|
|
@ -19,6 +19,54 @@ working_set_file_default_settings(Working_Set *working_set, Editing_File *file){
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
file_change_notification_check(System_Functions *system, Working_Set *working_set, Editing_File *file){
|
||||
if (file->canon.name_size > 0 && !file->settings.unimportant){
|
||||
String_Const_u8 name = SCu8(file->canon.name_space, file->canon.name_size);
|
||||
File_Attributes attributes = system->quick_file_attributes(name);
|
||||
if (attributes.last_write_time > file->attributes.last_write_time){
|
||||
if (!HasFlag(file->state.dirty, DirtyState_UnloadedChanges)){
|
||||
file_add_dirty_flag(file, DirtyState_UnloadedChanges);
|
||||
dll_insert_back(&working_set->has_reloaded_sentinel,
|
||||
&file->reloaded_node);
|
||||
system->signal_step(0);
|
||||
}
|
||||
}
|
||||
file->attributes = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
file_change_notification_thread_main(void *ptr){
|
||||
Models *models = (Models*)ptr;
|
||||
System_Functions *system = models->system;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
for (;;){
|
||||
system->sleep(Thousand(250));
|
||||
Mutex_Lock lock(system, working_set->mutex);
|
||||
if (working_set->active_file_count > 0){
|
||||
i32 check_count = working_set->active_file_count/16;
|
||||
check_count = clamp(1, check_count, 100);
|
||||
Node *used = &working_set->active_file_sentinel;
|
||||
Node *node = working_set->sync_check_iterator;
|
||||
if (node == 0 || node == used){
|
||||
node = used->next;
|
||||
}
|
||||
for (i32 i = 0; i < check_count; i += 1){
|
||||
Editing_File *file = CastFromMember(Editing_File, main_chain_node, node);
|
||||
node = node->next;
|
||||
if (node == used){
|
||||
node = node->next;
|
||||
}
|
||||
file_change_notification_check(system, working_set, file);
|
||||
}
|
||||
working_set->sync_check_iterator = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal Editing_File*
|
||||
working_set_allocate_file(Working_Set *working_set, Lifetime_Allocator *lifetime_allocator){
|
||||
Editing_File *file = working_set->free_files;
|
||||
|
@ -47,6 +95,9 @@ working_set_allocate_file(Working_Set *working_set, Lifetime_Allocator *lifetime
|
|||
|
||||
internal void
|
||||
working_set_free_file(Heap *heap, Working_Set *working_set, Editing_File *file){
|
||||
if (working_set->sync_check_iterator == &file->main_chain_node){
|
||||
working_set->sync_check_iterator = working_set->sync_check_iterator->next;
|
||||
}
|
||||
dll_remove(&file->main_chain_node);
|
||||
dll_remove(&file->touch_node);
|
||||
working_set->active_file_count -= 1;
|
||||
|
@ -65,8 +116,9 @@ working_set_get_file(Working_Set *working_set, Buffer_ID id){
|
|||
}
|
||||
|
||||
internal void
|
||||
working_set_init(System_Functions *system, Working_Set *working_set){
|
||||
working_set_init(Models *models, Working_Set *working_set){
|
||||
block_zero_struct(working_set);
|
||||
System_Functions *system = models->system;
|
||||
working_set->arena = make_arena_system(system);
|
||||
|
||||
working_set->id_counter = 1;
|
||||
|
@ -82,6 +134,10 @@ working_set_init(System_Functions *system, Working_Set *working_set){
|
|||
working_set->id_to_ptr_table = make_table_u64_u64(allocator, slot_count);
|
||||
working_set->canon_table = make_table_Data_u64(allocator, slot_count);
|
||||
working_set->name_table = make_table_Data_u64(allocator, slot_count);
|
||||
|
||||
dll_init_sentinel(&working_set->has_reloaded_sentinel);
|
||||
working_set->mutex = system->mutex_make();
|
||||
working_set->file_change_thread = system->thread_launch(file_change_notification_thread_main, models);
|
||||
}
|
||||
|
||||
internal Editing_File*
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#define FRED_WORKING_SET_H
|
||||
|
||||
struct Working_Set{
|
||||
// NOTE(allen): After initialization of file_change_thread
|
||||
// the members of this struct should only be accessed by a thread
|
||||
// who owns the mutex member.
|
||||
|
||||
Arena arena;
|
||||
|
||||
Editing_File *free_files;
|
||||
|
@ -32,15 +36,22 @@ struct Working_Set{
|
|||
Table_Data_u64 canon_table;
|
||||
Table_Data_u64 name_table;
|
||||
|
||||
Node *sync_check_iterator;
|
||||
Node has_reloaded_sentinel;
|
||||
System_Mutex mutex;
|
||||
System_Thread file_change_thread;
|
||||
|
||||
i32 default_display_width;
|
||||
i32 default_minimum_base_display_width;
|
||||
|
||||
// TODO(allen): do(update clipboard system to exist fully in the custom layer)
|
||||
// NOTE(allen): These members have nothing to do with the working set or
|
||||
// the mutex that gaurds the other members.
|
||||
String_Const_u8 clipboards[64];
|
||||
i32 clipboard_size;
|
||||
i32 clipboard_max_size;
|
||||
i32 clipboard_current;
|
||||
i32 clipboard_rolling;
|
||||
|
||||
i32 default_display_width;
|
||||
i32 default_minimum_base_display_width;
|
||||
};
|
||||
|
||||
internal void
|
||||
|
|
|
@ -28,6 +28,8 @@ link_system_code(void){
|
|||
SYSLINK(wake_up_timer_create);
|
||||
SYSLINK(wake_up_timer_release);
|
||||
SYSLINK(wake_up_timer_set);
|
||||
SYSLINK(signal_step);
|
||||
SYSLINK(sleep);
|
||||
|
||||
SYSLINK(post_clipboard);
|
||||
|
||||
|
|
|
@ -270,8 +270,8 @@ handle_type_ptr(void *ptr){
|
|||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
system_schedule_step(){
|
||||
PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0);
|
||||
system_schedule_step(u32 code){
|
||||
PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, code, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
@ -894,6 +894,17 @@ Sys_Wake_Up_Timer_Set_Sig(system_wake_up_timer_set){
|
|||
}
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Signal_Step_Sig(system_signal_step){
|
||||
system_schedule_step(code);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Sleep_Sig(system_sleep){
|
||||
u32 milliseconds = (u32)(microseconds/Thousand(1));
|
||||
Sleep(milliseconds);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal DWORD
|
||||
|
@ -1919,7 +1930,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
|
||||
// NOTE(allen): schedule another step if needed
|
||||
if (result.animating){
|
||||
system_schedule_step();
|
||||
system_schedule_step(0);
|
||||
}
|
||||
|
||||
// NOTE(allen): sleep a bit to cool off :)
|
||||
|
|
|
@ -375,7 +375,7 @@ int_color_from_colorref(COLORREF ref, int_color alpha_from){
|
|||
}
|
||||
|
||||
internal void
|
||||
system_schedule_step();
|
||||
system_schedule_step(u32 code);
|
||||
|
||||
internal UINT_PTR CALLBACK
|
||||
color_picker_hook(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam){
|
||||
|
@ -428,7 +428,7 @@ color_picker_hook(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam){
|
|||
if(*picker->dest != new_color)
|
||||
{
|
||||
*picker->dest = new_color;
|
||||
system_schedule_step();
|
||||
system_schedule_step(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue