got file saving working without exchange system
This commit is contained in:
parent
d5a07a9732
commit
2e8ea5f07f
240
4ed.cpp
240
4ed.cpp
|
@ -4149,20 +4149,6 @@ App_Step_Sig(app_step){
|
|||
*vars = result.vars;
|
||||
view->scroll_region = result.region;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO(allen): This is perhaps not the best system...
|
||||
// The problem is that the exact region and scroll position is pretty important
|
||||
// for some commands, so this is here to eliminate the one frame of lag.
|
||||
// Going to leave this here for now because the order of events is going to
|
||||
// change a lot soon anyway.// NOTE(allen):
|
||||
for (dll_items(panel, used_panels)){
|
||||
view = panel->view;
|
||||
Assert(view->current_scroll);
|
||||
view->current_scroll = ;
|
||||
gui_get_scroll_vars(&view->gui_target, view->showing_ui, view->current_scroll, &view->scroll_region);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
update_command_data(vars, cmd);
|
||||
|
@ -4371,170 +4357,6 @@ App_Step_Sig(app_step){
|
|||
|
||||
update_command_data(vars, cmd);
|
||||
|
||||
Temp_Memory file_temp = begin_temp_memory(&models->mem.part);
|
||||
|
||||
#if 0
|
||||
// NOTE(allen): Simulate what use to happen on the system side
|
||||
// for processing file exchange.
|
||||
{
|
||||
File_Exchange *files = &models->files;
|
||||
File_Slot *file;
|
||||
int d = 0;
|
||||
|
||||
for (file = files->active.next;
|
||||
file != &files->active;
|
||||
file = file->next){
|
||||
++d;
|
||||
|
||||
if (file->flags & FEx_Save){
|
||||
Assert((file->flags & FEx_Request) == 0);
|
||||
file->flags &= (~FEx_Save);
|
||||
if (system->file_save(file->filename,
|
||||
(char*)file->data, file->size)){
|
||||
file->flags |= FEx_Save_Complete;
|
||||
}
|
||||
else{
|
||||
file->flags |= FEx_Save_Failed;
|
||||
}
|
||||
app_result.animating = 1;
|
||||
}
|
||||
|
||||
if (file->flags & FEx_Request){
|
||||
Assert((file->flags & FEx_Save) == 0);
|
||||
file->flags &= (~FEx_Request);
|
||||
|
||||
File_Loading loading = system->file_load_begin(file->filename);
|
||||
|
||||
if (loading.exists){
|
||||
char *data = push_array(&models->mem.part, char, loading.size);
|
||||
if (system->file_load_end(loading, data)){
|
||||
file->flags |= FEx_Ready;
|
||||
file->data = (byte*)data;
|
||||
file->size = loading.size;
|
||||
}
|
||||
}
|
||||
else{
|
||||
system->file_load_end(loading, 0);
|
||||
file->flags |= FEx_Not_Exist;
|
||||
}
|
||||
|
||||
app_result.animating = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int free_list_count = 0;
|
||||
for (file = files->free_list.next;
|
||||
file != &files->free_list;
|
||||
file = file->next){
|
||||
++free_list_count;
|
||||
}
|
||||
|
||||
if (files->free_list.next != &files->free_list){
|
||||
Assert(free_list_count != 0);
|
||||
ex__insert_range(files->free_list.next,
|
||||
files->free_list.prev,
|
||||
&files->available);
|
||||
files->num_active -= free_list_count;
|
||||
}
|
||||
|
||||
ex__check(files);
|
||||
}
|
||||
|
||||
// NOTE(allen): processing sys app bindings
|
||||
{
|
||||
File_Exchange *files = &models->files;
|
||||
Mem_Options *mem = &models->mem;
|
||||
General_Memory *general = &mem->general;
|
||||
|
||||
for (i32 i = 0; i < vars->sys_app_count; ++i){
|
||||
Sys_App_Binding *binding;
|
||||
b32 remove = 0;
|
||||
b32 failed = 0;
|
||||
binding = vars->sys_app_bindings + i;
|
||||
|
||||
Editing_File *ed_file;
|
||||
Editing_File_Preload preload_settings;
|
||||
char *filename;
|
||||
|
||||
Working_Set *working_set = &models->working_set;
|
||||
File_Ready_Result file_result =
|
||||
exchange_file_ready(files, binding->sys_id);
|
||||
|
||||
if (file_result.ready){
|
||||
ed_file = working_set_get_active_file(working_set, binding->app_id);
|
||||
Assert(ed_file);
|
||||
|
||||
filename = exchange_file_filename(files, binding->sys_id);
|
||||
preload_settings = ed_file->preload;
|
||||
if (file_result.exists){
|
||||
String val = make_string((char*)file_result.data, file_result.size);
|
||||
file_create_from_string(system, models, ed_file, filename, val);
|
||||
|
||||
if (ed_file->settings.tokens_exist){
|
||||
file_first_lex_parallel(system, general, ed_file);
|
||||
}
|
||||
|
||||
if ((binding->success & SysAppCreateView) && binding->panel != 0){
|
||||
view_file_in_panel(cmd, binding->panel, ed_file);
|
||||
}
|
||||
|
||||
for (View_Iter iter = file_view_iter_init(&models->layout, ed_file, 0);
|
||||
file_view_iter_good(iter);
|
||||
iter = file_view_iter_next(iter)){
|
||||
view_measure_wraps(general, iter.view);
|
||||
view_cursor_move(iter.view, preload_settings.start_line, 0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (binding->fail & SysAppCreateNewBuffer){
|
||||
file_create_empty(system, models, ed_file, filename);
|
||||
if (binding->fail & SysAppCreateView){
|
||||
view_file_in_panel(cmd, binding->panel, ed_file);
|
||||
}
|
||||
}
|
||||
else{
|
||||
working_set_remove(system, &models->working_set, ed_file->name.source_path);
|
||||
working_set_free_file(&models->working_set, ed_file);
|
||||
}
|
||||
}
|
||||
|
||||
exchange_free_file(files, binding->sys_id);
|
||||
remove = 1;
|
||||
}
|
||||
|
||||
// TODO(allen): Switch to multiple return struct.
|
||||
byte *data;
|
||||
i32 size, max;
|
||||
|
||||
if (exchange_file_save_complete(files, binding->sys_id, &data, &size, &max, &failed)){
|
||||
Assert(remove == 0);
|
||||
|
||||
if (data){
|
||||
general_memory_free(general, data);
|
||||
exchange_clear_file(files, binding->sys_id);
|
||||
}
|
||||
|
||||
Editing_File *file = working_set_get_active_file(working_set, binding->app_id);
|
||||
if (file){
|
||||
file_synchronize_times(system, file, file->name.source_path.str);
|
||||
}
|
||||
|
||||
exchange_free_file(files, binding->sys_id);
|
||||
remove = 1;
|
||||
|
||||
// if (failed) { TODO(allen): saving error, now what? }
|
||||
}
|
||||
|
||||
if (remove){
|
||||
*binding = vars->sys_app_bindings[--vars->sys_app_count];
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
end_temp_memory(file_temp);
|
||||
|
||||
// NOTE(allen): process as many delayed actions as possible
|
||||
if (models->delay1.count > 0){
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
@ -4596,59 +4418,11 @@ App_Step_Sig(app_step){
|
|||
view_file_in_panel(cmd, panel, file);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
String filename = string;
|
||||
i32 file_id;
|
||||
|
||||
result.file = working_set_contains(system, working_set, filename);
|
||||
if (result.file == 0){
|
||||
result.file = working_set_alloc_always(working_set, general);
|
||||
if (result.file){
|
||||
file_id = exchange_request_file(files, filename.str, filename.size);
|
||||
if (file_id){
|
||||
file_init_strings(result.file);
|
||||
file_set_name(working_set, result.file, filename.str);
|
||||
file_set_to_loading(result.file);
|
||||
working_set_add(system, working_set, result.file, general);
|
||||
|
||||
result.sys_id = file_id;
|
||||
result.file_index = result.file->id.id;
|
||||
}
|
||||
else{
|
||||
working_set_free_file(working_set, result.file);
|
||||
delayed_action_repush(&models->delay2, act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.is_new){
|
||||
if (result.file){
|
||||
Assert(result.sys_id);
|
||||
Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index);
|
||||
binding->success = (act->type == DACT_OPEN) ? SysAppCreateView : 0;
|
||||
binding->fail = 0;
|
||||
binding->panel = panel;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (act->type == DACT_OPEN){
|
||||
Assert(result.file);
|
||||
if (!result.file->state.is_loading){
|
||||
view_file_in_panel(cmd, panel, result.file);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
|
||||
case DACT_SET_LINE:
|
||||
{
|
||||
// TODO(allen): deduplicate
|
||||
Editing_File *file = 0;
|
||||
if (panel){
|
||||
file = panel->view->file_data.file;
|
||||
}
|
||||
|
@ -4668,7 +4442,6 @@ App_Step_Sig(app_step){
|
|||
case DACT_SAVE:
|
||||
case DACT_SAVE_AS:
|
||||
{
|
||||
#if 0
|
||||
if (!file){
|
||||
if (panel){
|
||||
View *view = panel->view;
|
||||
|
@ -4679,23 +4452,14 @@ App_Step_Sig(app_step){
|
|||
file = working_set_lookup_file(working_set, string);
|
||||
}
|
||||
}
|
||||
// TODO(allen): We could handle the case where someone tries to save the same thing
|
||||
// twice... that would be nice to have under control.
|
||||
|
||||
if (file && buffer_get_sync(file) != SYNC_GOOD){
|
||||
i32 sys_id = file_save(system, files, mem, file, file->name.source_path.str);
|
||||
if (sys_id){
|
||||
if (file_save(system, mem, file, string.str)){
|
||||
if (act->type == DACT_SAVE_AS){
|
||||
file_set_name(working_set, file, string.str);
|
||||
}
|
||||
// TODO(allen): This is fishy! Shouldn't we bind it to a file name instead? This file
|
||||
// might be killed before we get notified that the saving is done!
|
||||
app_push_file_binding(vars, sys_id, file->id.id);
|
||||
}
|
||||
else{
|
||||
delayed_action_repush(&models->delay2, act);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
|
||||
case DACT_NEW:
|
||||
|
|
248
4ed_exchange.cpp
248
4ed_exchange.cpp
|
@ -9,252 +9,8 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#if 0
|
||||
enum File_Exchange_Flag{
|
||||
FEx_Request = 0x1,
|
||||
FEx_Ready = 0x2,
|
||||
FEx_Not_Exist = 0x4,
|
||||
FEx_Save = 0x8,
|
||||
FEx_Save_Complete = 0x10,
|
||||
FEx_Save_Failed = 0x20
|
||||
};
|
||||
|
||||
#define FileNameMax (1 << 9)
|
||||
|
||||
struct File_Slot{
|
||||
File_Slot *next, *prev;
|
||||
byte *data;
|
||||
i32 size, max;
|
||||
char *filename;
|
||||
i32 filename_len;
|
||||
u32 flags;
|
||||
};
|
||||
inline File_Slot
|
||||
file_slot_zero(){
|
||||
File_Slot slot={0};
|
||||
return(slot);
|
||||
}
|
||||
|
||||
struct File_Exchange{
|
||||
File_Slot available, active, free_list;
|
||||
File_Slot *files;
|
||||
i32 num_active, max;
|
||||
};
|
||||
|
||||
internal void
|
||||
ex__file_insert(File_Slot *pos, File_Slot *file){
|
||||
pos->next->prev = file;
|
||||
file->next = pos->next;
|
||||
pos->next = file;
|
||||
file->prev = pos;
|
||||
}
|
||||
|
||||
void
|
||||
ex__insert_range(File_Slot *start, File_Slot *end, File_Slot *pos){
|
||||
end->next->prev = start->prev;
|
||||
start->prev->next = end->next;
|
||||
|
||||
end->next = pos->next;
|
||||
start->prev = pos;
|
||||
pos->next->prev = end;
|
||||
pos->next = start;
|
||||
}
|
||||
|
||||
internal void
|
||||
ex__file_remove(File_Slot *file){
|
||||
file->next->prev = file->prev;
|
||||
file->prev->next = file->next;
|
||||
}
|
||||
|
||||
internal void
|
||||
ex__check_file(File_Slot *pos){
|
||||
File_Slot *file = pos;
|
||||
|
||||
Assert(pos == pos->next->prev);
|
||||
|
||||
for (pos = pos->next;
|
||||
file != pos;
|
||||
pos = pos->next){
|
||||
Assert(pos == pos->next->prev);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
ex__check(File_Exchange *file_exchange){
|
||||
ex__check_file(&file_exchange->available);
|
||||
ex__check_file(&file_exchange->active);
|
||||
ex__check_file(&file_exchange->free_list);
|
||||
}
|
||||
|
||||
internal void
|
||||
ex__clear(File_Slot *file){
|
||||
file->data = 0;
|
||||
file->size = 0;
|
||||
file->max = 0;
|
||||
file->flags = 0;
|
||||
}
|
||||
|
||||
internal File_Slot*
|
||||
ex__get_file(File_Exchange *files){
|
||||
File_Slot *file;
|
||||
|
||||
++files->num_active;
|
||||
|
||||
file = files->available.next;
|
||||
ex__file_remove(file);
|
||||
ex__clear(file);
|
||||
ex__file_insert(&files->active, file);
|
||||
ex__check(files);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
internal void
|
||||
ex__set_filename(File_Slot *file, char *filename, int len){
|
||||
memcpy(file->filename, filename, len);
|
||||
file->filename[len] = 0;
|
||||
file->filename_len = len;
|
||||
}
|
||||
|
||||
internal i32
|
||||
exchange_request_file(File_Exchange *files, char *filename, int len){
|
||||
i32 result = 0;
|
||||
|
||||
if (len+1 < FileNameMax){
|
||||
if (files->num_active < files->max){
|
||||
File_Slot *file = ex__get_file(files);
|
||||
ex__set_filename(file, filename, len);
|
||||
|
||||
file->flags |= FEx_Request;
|
||||
result = (int)(file - files->files) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct File_Ready_Result{
|
||||
byte *data;
|
||||
i32 size;
|
||||
i32 max;
|
||||
b32 exists;
|
||||
b32 ready;
|
||||
};
|
||||
|
||||
internal File_Ready_Result
|
||||
exchange_file_ready(File_Exchange *files, i32 file_id){
|
||||
File_Ready_Result result = {0};
|
||||
File_Slot *file = 0;
|
||||
|
||||
if (file_id > 0 && file_id <= files->max){
|
||||
file = files->files + file_id - 1;
|
||||
if (file->flags & FEx_Ready){
|
||||
result.data = file->data;
|
||||
result.size = file->size;
|
||||
result.max = file->max;
|
||||
result.exists = 1;
|
||||
result.ready = 1;
|
||||
}
|
||||
if (file->flags & FEx_Not_Exist){
|
||||
result.data = 0;
|
||||
result.size = 0;
|
||||
result.max = 0;
|
||||
result.exists = 0;
|
||||
result.ready = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
exchange_file_does_not_exist(File_Exchange *files, i32 file_id){
|
||||
b32 result = 1;
|
||||
File_Slot *slot;
|
||||
|
||||
if (file_id > 0 && file_id <= files->max){
|
||||
slot = files->files + file_id - 1;
|
||||
if (!(slot->flags & FEx_Not_Exist)){
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal i32
|
||||
exchange_save_file(File_Exchange *files, char *filename, int len,
|
||||
byte *data, int size, int max){
|
||||
i32 result = 0;
|
||||
|
||||
if (len+1 < FileNameMax){
|
||||
if (files->num_active < files->max){
|
||||
File_Slot *file = ex__get_file(files);
|
||||
ex__set_filename(file, filename, len);
|
||||
|
||||
file->flags |= FEx_Save;
|
||||
file->data = data;
|
||||
file->size = size;
|
||||
file->max = max;
|
||||
|
||||
result = (int)(file - files->files) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
exchange_file_save_complete(File_Exchange *files, i32 file_id,
|
||||
byte **data, int *size, int *max, int *failed){
|
||||
b32 result = 0;
|
||||
|
||||
if (file_id > 0 && file_id <= files->max){
|
||||
File_Slot *file = files->files + file_id - 1;
|
||||
if (file->flags & FEx_Save_Complete || file->flags & FEx_Save_Failed){
|
||||
*data = file->data;
|
||||
*size = file->size;
|
||||
*max = file->max;
|
||||
result = 1;
|
||||
|
||||
*failed = (file->flags & FEx_Save_Complete)?(1):(0);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal char*
|
||||
exchange_file_filename(File_Exchange *files, i32 file_id, i32 *size = 0){
|
||||
char *result = 0;
|
||||
|
||||
if (file_id > 0 && file_id <= files->max){
|
||||
File_Slot *file = files->files + file_id - 1;
|
||||
result = file->filename;
|
||||
if (size) *size = file->filename_len;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
exchange_free_file(File_Exchange *files, i32 file_id){
|
||||
if (file_id > 0 && file_id <= files->max){
|
||||
File_Slot *file = files->files + file_id - 1;
|
||||
ex__file_remove(file);
|
||||
ex__file_insert(&files->free_list, file);
|
||||
ex__check(files);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
exchange_clear_file(File_Exchange *files, i32 file_id){
|
||||
if (file_id > 0 && file_id <= files->max){
|
||||
File_Slot *file = files->files + file_id - 1;
|
||||
ex__clear(file);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// NOTE(allen): Uhhh.... is it just me or did it get awkward
|
||||
// in here when I deleted all the file exchange stuff?
|
||||
|
||||
internal b32
|
||||
queue_job_is_pending(Work_Queue *queue, u32 job_id){
|
||||
|
|
|
@ -435,9 +435,9 @@ file_synchronize_times(System_Functions *system, Editing_File *file, char *filen
|
|||
file->state.sync = buffer_get_sync(file);
|
||||
}
|
||||
|
||||
internal i32
|
||||
internal b32
|
||||
file_save(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){
|
||||
i32 result = 0;
|
||||
b32 result = 0;
|
||||
|
||||
i32 max, size;
|
||||
b32 dos_write_mode = file->settings.dos_write_mode;
|
||||
|
@ -3520,47 +3520,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set,
|
|||
}
|
||||
|
||||
else if (key.character == '\n' || key.character == '\t'){
|
||||
#if 0
|
||||
result.made_a_change = 1;
|
||||
if (key.modifiers[MDFR_CONTROL_INDEX] ||
|
||||
key.modifiers[MDFR_ALT_INDEX]){
|
||||
result.hit_ctrl_newline = 1;
|
||||
}
|
||||
else{
|
||||
result.hit_newline = 1;
|
||||
if (mode.fast_folder_select){
|
||||
Hot_Directory_Match match;
|
||||
char front_name_space[256];
|
||||
String front_name = make_fixed_width_string(front_name_space);
|
||||
get_front_of_directory(&front_name, *mode.string);
|
||||
|
||||
match =
|
||||
hot_directory_first_match(mode.hot_directory, front_name, 1, 1, mode.case_sensitive);
|
||||
|
||||
if (mode.try_to_match && !match.filename.str){
|
||||
match = hot_directory_first_match(mode.hot_directory, front_name, 1, 0, mode.case_sensitive);
|
||||
}
|
||||
if (match.filename.str){
|
||||
if (match.is_folder){
|
||||
set_last_folder(mode.string, match.filename, mode.hot_directory->slash);
|
||||
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
|
||||
result.hit_newline = 0;
|
||||
}
|
||||
else{
|
||||
if (mode.try_to_match){
|
||||
mode.string->size = reverse_seek_slash(*mode.string) + 1;
|
||||
append(mode.string, match.filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (mode.try_to_match){
|
||||
result.no_file_match = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// NOTE(allen): do nothing!
|
||||
}
|
||||
|
||||
else if (key.keycode == key_esc){
|
||||
|
|
|
@ -266,17 +266,8 @@ struct System_Functions{
|
|||
char slash;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct Write_Event{
|
||||
Write_Event *next, *prev;
|
||||
String filename;
|
||||
u64 time_stamp;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Exchange{
|
||||
Thread_Exchange thread;
|
||||
// Write_Event write_event_sentinel;
|
||||
};
|
||||
|
||||
// BOTTOM
|
||||
|
|
Loading…
Reference in New Issue