diff --git a/4ed.cpp b/4ed.cpp index 6c4d47d5..1b361f3b 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -390,7 +390,7 @@ COMMAND_DECL(save){ USE_VIEW(view); REQ_FILE(file, view); - if (!file->is_dummy && file_is_ready(file) && buffer_needs_save(file)){ + if (!file->is_dummy && file_is_ready(file) && buffer_can_save(file)){ save_file(system, &models->mem, file); } } @@ -1680,6 +1680,38 @@ App_Step_Sig(app_step){ dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size); } + // NOTE(allen): check files are up to date + { + b32 mem_too_small = 0; + i32 size = 0; + i32 buffer_size = (32 << 10); + + Partition *part = &models->mem.part; + Temp_Memory temp = begin_temp_memory(part); + char *buffer = push_array(part, char, buffer_size); + + 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_Canon_Name canon; + if (get_canon_name(system, &canon, make_string(buffer, size))){ + Editing_File *file = working_set_canon_contains(working_set, canon.name); + if (file){ + if (file->state.ignore_behind_os == 0){ + file_mark_behind_os(file); + } + else{ + file->state.ignore_behind_os = 0; + } + } + } + } + + end_temp_memory(temp); + } + #if 0 // NOTE(allen): check files are up to date if (!input->first_step){ diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 088aeb95..5f2ca7a1 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -1031,7 +1031,7 @@ DOC_SEE(Buffer_Create_Flag) if (system->load_file(handle, buffer, size)){ file = working_set_alloc_always(working_set, general); if (file){ - buffer_bind_file(general, working_set, file, canon.name); + buffer_bind_file(system, general, working_set, file, canon.name); buffer_bind_name(general, working_set, file, fname); init_normal_file(system, models, file, buffer, size); fill_buffer_summary(&result, file, cmd); diff --git a/4ed_file.cpp b/4ed_file.cpp index a1886eaa..6506de12 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -144,6 +144,7 @@ struct Editing_File_State{ Text_Effect paste_effect; File_Sync_State sync; + u32 ignore_behind_os; File_Edit_Positions edit_pos_space[16]; File_Edit_Positions *edit_poss[16]; @@ -769,6 +770,18 @@ buffer_needs_save(Editing_File *file){ return(result); } +inline b32 +buffer_can_save(Editing_File *file){ + b32 result = 0; + if (!file->settings.unimportant){ + if (file->state.sync == SYNC_UNSAVED || + file->state.sync == SYNC_BEHIND_OS){ + result = 1; + } + } + return(result); +} + inline b32 file_is_ready(Editing_File *file){ b32 result = 0; @@ -892,7 +905,7 @@ buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *fil } internal void -buffer_bind_file(General_Memory *general, Working_Set *working_set, +buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String canon_filename){ Assert(file->name.live_name.size == 0 && file->name.source_path.size == 0 && @@ -901,17 +914,19 @@ buffer_bind_file(General_Memory *general, Working_Set *working_set, file->canon.name = make_fixed_width_string(file->canon.name_); copy(&file->canon.name, canon_filename); + system->add_listener(file->canon.name_); b32 result = working_set_canon_add(general, working_set, file, file->canon.name); Assert(result); AllowLocal(result); } internal void -buffer_unbind_file(Working_Set *working_set, Editing_File *file){ +buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_File *file){ Assert(file->name.live_name.size == 0 && file->name.source_path.size == 0 && file->name.extension.size == 0); Assert(file->canon.name.size != 0); + system->remove_listener(file->canon.name_); working_set_canon_remove(working_set, file->canon.name); file->canon.name.size = 0; } diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index ce1559b5..a554435d 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -788,10 +788,12 @@ file_synchronize_times(System_Functions *system, Editing_File *file){ internal b32 save_file_to_name(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){ b32 result = 0; + b32 using_actual_filename = 0; if (!filename){ terminate_with_null(&file->canon.name); filename = file->canon.name.str; + using_actual_filename = 1; } if (filename){ @@ -832,6 +834,9 @@ save_file_to_name(System_Functions *system, Mem_Options *mem, Editing_File *file } result = system->save_file(filename, data, size); + if (result && using_actual_filename){ + file->state.ignore_behind_os = 1; + } file_mark_clean(file); @@ -861,9 +866,9 @@ buffer_link_to_new_file(System_Functions *system, General_Memory *general, Worki if (get_canon_name(system, &canon_name, filename)){ buffer_unbind_name(working_set, file); if (file->canon.name.size != 0){ - buffer_unbind_file(working_set, file); + buffer_unbind_file(system, working_set, file); } - buffer_bind_file(general, working_set, file, canon_name.name); + buffer_bind_file(system, general, working_set, file, canon_name.name); buffer_bind_name(general, working_set, file, filename); result = 1; } @@ -3228,7 +3233,7 @@ view_open_file(System_Functions *system, Models *models, View *view, String file file = working_set_alloc_always(working_set, general); - buffer_bind_file(general, working_set, file, canon_name.name); + buffer_bind_file(system, general, working_set, file, canon_name.name); buffer_bind_name(general, working_set, file, filename); i32 size = system->load_size(handle); @@ -3294,7 +3299,7 @@ view_interactive_new_file(System_Functions *system, Models *models, View *view, file = working_set_alloc_always(working_set, general); - buffer_bind_file(general, working_set, file, canon_name.name); + buffer_bind_file(system, general, working_set, file, canon_name.name); buffer_bind_name(general, working_set, file, filename); init_normal_file(system, models, file, 0, 0); @@ -3313,7 +3318,7 @@ kill_file(System_Functions *system, Models *models, Editing_File *file){ if (file && !file->settings.never_kill){ buffer_unbind_name(working_set, file); - buffer_unbind_file(working_set, file); + buffer_unbind_file(system, working_set, file); file_close(system, &models->mem.general, file); working_set_free_file(working_set, file); diff --git a/4ed_system.h b/4ed_system.h index 4b9f4513..826d21d5 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -38,6 +38,9 @@ typedef Sys_Add_Listener_Sig(System_Add_Listener); #define Sys_Remove_Listener_Sig(name) b32 name(char *filename) typedef Sys_Remove_Listener_Sig(System_Remove_Listener); +#define Sys_Get_File_Change_Sig(name) i32 name(char *buffer, i32 max, b32 *mem_too_small, i32 *required_size) +typedef Sys_Get_File_Change_Sig(System_Get_File_Change); + #define Sys_Load_Handle_Sig(name) b32 name(char *filename, Plat_Handle *handle_out) typedef Sys_Load_Handle_Sig(System_Load_Handle); @@ -209,11 +212,12 @@ typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message); struct System_Functions{ - // files (tracked api): 9 + // files (tracked api): 10 System_Set_File_List *set_file_list; System_Get_Canonical *get_canonical; - System_Add_Listener *add_listener; + System_Add_Listener *add_listener; System_Remove_Listener *remove_listener; + System_Get_File_Change *get_file_change; System_Load_Handle *load_handle; System_Load_Size *load_size; System_Load_File *load_file; diff --git a/build_all.bat b/build_all.bat index 6b7c1cf4..538444d3 100644 --- a/build_all.bat +++ b/build_all.bat @@ -26,7 +26,7 @@ popd pushd ..\build REM call "%CODE_DIR%\buildsuper.bat" ..\code\4coder_default_bindings.cpp -REM call "%CODE_DIR%\buildsuper.bat" ..\code\internal_4coder_tests.cpp +call "%CODE_DIR%\buildsuper.bat" ..\code\internal_4coder_tests.cpp REM call "%CODE_DIR%\buildsuper.bat" ..\code\power\4coder_casey.cpp REM call "%CODE_DIR%\buildsuper.bat" ..\4vim\4coder_chronal.cpp if %ERRORLEVEL% neq 0 (set FirstError=1) diff --git a/filetrack/4tech_file_track_win32.c b/filetrack/4tech_file_track_win32.c index 80f04696..0b11b1b8 100644 --- a/filetrack/4tech_file_track_win32.c +++ b/filetrack/4tech_file_track_win32.c @@ -684,7 +684,7 @@ expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size } File_Track_Result -get_change_event(File_Track_System *system, char *buffer, int32_t max){ +get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *size){ File_Track_Result result = FileTrack_NoMoreEvents; File_Track_Vars *vars = to_vars_(system); @@ -722,7 +722,9 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max){ info = (FILE_NOTIFY_INFORMATION*)(listener_buffer + offset); int32_t len = info->FileNameLength / 2; - if (listener.dir_name_len + 1 + len < max){ + int32_t req_size = listener.dir_name_len + 1 + len; + *size = req_size; + if (req_size < max){ int32_t pos = 0; char *src = listener.dir_name; for (int32_t i = 0; src[i]; ++i, ++pos){ @@ -734,7 +736,6 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max){ for (int32_t i = 0; i < len; ++i, ++pos){ buffer[pos] = (char)info->FileName[i]; } - buffer[pos] = 0; result = FileTrack_Good; } diff --git a/internal_4coder_tests.cpp b/internal_4coder_tests.cpp index df86fd2e..82706f7d 100644 --- a/internal_4coder_tests.cpp +++ b/internal_4coder_tests.cpp @@ -28,7 +28,6 @@ Allen Webster // These tests do not verify the correctness of the output. CUSTOM_COMMAND_SIG(load_lots_of_files){ - // NOTE(allen): This timing restriction is based on 4GHz and 60fps // 4G / 60 ~= 70M Reserving most of that time for rendering and hopefully idling // I set the goal of 10M for all tests. diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 5e541099..7c7a3228 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -1210,6 +1210,26 @@ Sys_Remove_Listener_Sig(system_remove_listener){ return(result); } +internal +Sys_Get_File_Change_Sig(system_get_file_change){ + i32 result = 0; + + i32 size = 0; + i32 get_result = get_change_event(&win32vars.track, buffer, max, &size); + + *required_size = size; + *mem_too_small = 0; + if (get_result == FileTrack_Good){ + result = 1; + } + else if (get_result == FileTrack_MemoryTooSmall){ + *mem_too_small = 1; + result = 1; + } + + return(result); +} + internal Sys_Load_Handle_Sig(system_load_handle){ b32 result = 0; @@ -1664,6 +1684,7 @@ Win32LoadSystemCode(){ win32vars.system.get_canonical = system_get_canonical; win32vars.system.add_listener = system_add_listener; win32vars.system.remove_listener = system_remove_listener; + win32vars.system.get_file_change = system_get_file_change; win32vars.system.load_handle = system_load_handle; win32vars.system.load_size = system_load_size; win32vars.system.load_file = system_load_file;