windows unique file hash
This commit is contained in:
parent
b343a1c4ae
commit
5538468eab
|
@ -1,5 +1,5 @@
|
|||
// Set which customization you want to use with this define or write your own
|
||||
#define Custom_Current Custom_HandmadeHero
|
||||
#define Custom_Current Custom_Default
|
||||
|
||||
#define Custom_Default 0
|
||||
|
||||
|
|
183
4ed.cpp
183
4ed.cpp
|
@ -975,7 +975,7 @@ COMMAND_DECL(reopen){
|
|||
i32 index = 0;
|
||||
if (file_id){
|
||||
file_set_to_loading(file);
|
||||
index = (i32)(file - models->working_set.files);
|
||||
index = file->id.id;
|
||||
app_push_file_binding(vars, file_id, index);
|
||||
|
||||
view_set_file(view, file, models, system,
|
||||
|
@ -1026,7 +1026,7 @@ COMMAND_DECL(save){
|
|||
}
|
||||
}
|
||||
else{
|
||||
file = models->working_set.files + buffer_id;
|
||||
file = working_set_get_active_file(&models->working_set, buffer_id);
|
||||
|
||||
if (!file->state.is_dummy && file_is_ready(file)){
|
||||
delayed_save(delay, name, file);
|
||||
|
@ -1096,7 +1096,7 @@ COMMAND_DECL(kill_buffer){
|
|||
}
|
||||
|
||||
if (buffer_id != 0){
|
||||
file = working_set_get_file(&models->working_set, buffer_id, 1).file;
|
||||
file = working_set_get_active_file(&models->working_set, buffer_id);
|
||||
if (file){
|
||||
delayed_kill(delay, file);
|
||||
}
|
||||
|
@ -1730,47 +1730,46 @@ COMMAND_DECL(command_line){
|
|||
{
|
||||
Working_Set *working_set = &models->working_set;
|
||||
CLI_Process *procs = vars->cli_processes.procs, *proc = 0;
|
||||
Get_File_Result file = {};
|
||||
Editing_File *file = 0;
|
||||
b32 bind_to_new_view = !do_in_background;
|
||||
|
||||
if (vars->cli_processes.count < vars->cli_processes.max){
|
||||
if (buffer_id){
|
||||
file = working_set_get_file(working_set, buffer_id, 1);
|
||||
file = working_set_get_active_file(working_set, buffer_id);
|
||||
}
|
||||
else if (buffer_name){
|
||||
file.file = working_set_contains(working_set, make_string(buffer_name, buffer_name_len));
|
||||
file.index = (i32)(file.file - working_set->files);
|
||||
if (file.file == 0){
|
||||
file = working_set_get_available_file(working_set);
|
||||
if (file.file == 0){
|
||||
file = working_set_contains(working_set, make_string(buffer_name, buffer_name_len));
|
||||
if (file == 0){
|
||||
file = working_set_alloc_always(working_set, &models->mem.general);
|
||||
if (file == 0){
|
||||
// TODO(allen): feedback message - no available file
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file.file){
|
||||
if (file){
|
||||
i32 proc_count = vars->cli_processes.count;
|
||||
View_Iter iter;
|
||||
i32 i;
|
||||
|
||||
file_create_read_only(system, models, file.file, buffer_name);
|
||||
file.file->settings.unimportant = 1;
|
||||
table_add(&working_set->table, file.file->name.source_path, file.index);
|
||||
file_create_read_only(system, models, file, buffer_name);
|
||||
file->settings.unimportant = 1;
|
||||
table_add(&working_set->table, file->name.source_path, file->id.id);
|
||||
|
||||
for (i = 0; i < proc_count; ++i){
|
||||
if (procs[i].out_file == file.file){
|
||||
if (procs[i].out_file == file){
|
||||
if (flags & CLI_OverlapWithConflict)
|
||||
procs[i].out_file = 0;
|
||||
else
|
||||
file.file = 0;
|
||||
file = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (file.file){
|
||||
if (file){
|
||||
if (!(flags & CLI_AlwaysBindToView)){
|
||||
iter = file_view_iter_init(&models->layout, file.file, 0);
|
||||
iter = file_view_iter_init(&models->layout, file, 0);
|
||||
if (file_view_iter_good(iter)){
|
||||
bind_to_new_view = 0;
|
||||
}
|
||||
|
@ -1809,11 +1808,11 @@ COMMAND_DECL(command_line){
|
|||
}
|
||||
|
||||
if (bind_to_new_view){
|
||||
view_file_in_panel(command, panel, file.file);
|
||||
view_file_in_panel(command, panel, file);
|
||||
}
|
||||
|
||||
proc = procs + vars->cli_processes.count++;
|
||||
proc->out_file = file.file;
|
||||
proc->out_file = file;
|
||||
|
||||
if (!system->cli_call(path, script, &proc->cli)){
|
||||
--vars->cli_processes.count;
|
||||
|
@ -1844,7 +1843,7 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor
|
|||
buffer->ready = file_is_ready(file);
|
||||
|
||||
buffer->is_lexed = file->settings.tokens_exist;
|
||||
buffer->buffer_id = (int)(file - working_set->files);
|
||||
buffer->buffer_id = file->id.id;
|
||||
buffer->size = file->state.buffer.size;
|
||||
buffer->buffer_cursor_pos = file->state.cursor_pos;
|
||||
|
||||
|
@ -1871,7 +1870,7 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_
|
|||
|
||||
if (vptr->file){
|
||||
lock_level = view_lock_level(vptr);
|
||||
buffer_id = (int)(vptr->file - working_set->files);
|
||||
buffer_id = vptr->file->id.id;
|
||||
|
||||
if (lock_level <= 0){
|
||||
view->buffer_id = buffer_id;
|
||||
|
@ -1981,7 +1980,7 @@ extern "C"{
|
|||
Working_Set *working_set = &cmd->models->working_set;
|
||||
Editing_File *file;
|
||||
|
||||
file = working_set_get_file(working_set, buffer->buffer_id, 1).file;
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
if (file){
|
||||
file = (Editing_File*)file->node.next;
|
||||
fill_buffer_summary(buffer, file, working_set);
|
||||
|
@ -1995,11 +1994,11 @@ extern "C"{
|
|||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
Buffer_Summary buffer = {};
|
||||
Get_File_Result file;
|
||||
Editing_File *file;
|
||||
|
||||
file = working_set_get_file(working_set, index, 1);
|
||||
if (file.file){
|
||||
fill_buffer_summary(&buffer, file.file, working_set);
|
||||
file = working_set_get_active_file(working_set, index);
|
||||
if (file){
|
||||
fill_buffer_summary(&buffer, file, working_set);
|
||||
}
|
||||
|
||||
return(buffer);
|
||||
|
@ -2037,12 +2036,11 @@ extern "C"{
|
|||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Buffer_Summary buffer = {};
|
||||
Editing_File *file;
|
||||
Working_Set *working_set;
|
||||
i32 index;
|
||||
Working_Set *working_set = &cmd->models->working_set;
|
||||
File_ID id;
|
||||
|
||||
working_set = &cmd->models->working_set;
|
||||
if (table_find(&working_set->table, make_string(filename, len), &index)){
|
||||
file = working_set_get_file(working_set, index, 1).file;
|
||||
if (table_find(&working_set->table, make_string(filename, len), &id)){
|
||||
file = working_set_get_active_file(working_set, id);
|
||||
if (file){
|
||||
fill_buffer_summary(&buffer, file, working_set);
|
||||
}
|
||||
|
@ -2060,7 +2058,7 @@ extern "C"{
|
|||
|
||||
if (buffer->exists){
|
||||
working_set = &cmd->models->working_set;
|
||||
file = working_set_get_file(working_set, buffer->buffer_id, 1).file;
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
if (file && file_is_ready(file)){
|
||||
size = buffer_size(&file->state.buffer);
|
||||
result = 1;
|
||||
|
@ -2097,7 +2095,7 @@ extern "C"{
|
|||
if (buffer->exists){
|
||||
models = cmd->models;
|
||||
working_set = &models->working_set;
|
||||
file = working_set_get_file(working_set, buffer->buffer_id, 1).file;
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
if (file && file_is_ready(file)){
|
||||
size = buffer_size(&file->state.buffer);
|
||||
|
||||
|
@ -2139,7 +2137,7 @@ extern "C"{
|
|||
|
||||
if (buffer->exists){
|
||||
working_set = &cmd->models->working_set;
|
||||
file = working_set_get_file(working_set, buffer->buffer_id, 1).file;
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
if (file && file_is_ready(file)){
|
||||
size = buffer_size(&file->state.buffer);
|
||||
if (0 <= start && start <= end && end <= size){
|
||||
|
@ -2167,7 +2165,7 @@ extern "C"{
|
|||
if (buffer->exists){
|
||||
models = cmd->models;
|
||||
working_set = &models->working_set;
|
||||
file = working_set_get_file(working_set, buffer->buffer_id, 1).file;
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
if (file && file_is_ready(file)){
|
||||
size = buffer_size(&file->state.buffer);
|
||||
if (0 <= start && start <= end && end <= size){
|
||||
|
@ -2197,7 +2195,7 @@ extern "C"{
|
|||
|
||||
if (buffer->exists){
|
||||
working_set = &cmd->models->working_set;
|
||||
file = working_set_get_file(working_set, buffer->buffer_id, 1).file;
|
||||
file = working_set_get_active_file(working_set, buffer->buffer_id);
|
||||
if (file && file_is_ready(file)){
|
||||
result = 1;
|
||||
size = buffer_size(&file->state.buffer);
|
||||
|
@ -2365,7 +2363,7 @@ extern "C"{
|
|||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Live_Views *live_set;
|
||||
View *vptr;
|
||||
Get_File_Result file;
|
||||
Editing_File *file;
|
||||
Working_Set *working_set;
|
||||
Models *models;
|
||||
int result = 0;
|
||||
|
@ -2378,13 +2376,13 @@ extern "C"{
|
|||
if (view_id >= 0 && view_id < live_set->max){
|
||||
vptr = live_set->views + view_id;
|
||||
working_set = &models->working_set;
|
||||
file = working_set_get_file(working_set, buffer_id, 1);
|
||||
file = working_set_get_active_file(working_set, buffer_id);
|
||||
|
||||
if (file.file){
|
||||
if (file){
|
||||
result = 1;
|
||||
if (file.file != vptr->file){
|
||||
view_set_file(vptr, file.file, models,
|
||||
cmd->system, models->hooks[hook_open_file], &app_links);
|
||||
if (file != vptr->file){
|
||||
view_set_file(vptr, file, models, cmd->system,
|
||||
models->hooks[hook_open_file], &app_links);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3298,21 +3296,22 @@ App_Init_Sig(app_init){
|
|||
|
||||
// NOTE(allen): file setup
|
||||
{
|
||||
models->working_set.file_count = 0;
|
||||
models->working_set.file_max = 119;
|
||||
models->working_set.files = push_array(
|
||||
partition, Editing_File, models->working_set.file_max + 1);
|
||||
|
||||
models->working_set.files[0].state.is_dummy = 1;
|
||||
Editing_File *files, *null_file;
|
||||
i16 init_count = 128;
|
||||
|
||||
dll_init_sentinel(&models->working_set.free_sentinel);
|
||||
dll_init_sentinel(&models->working_set.used_sentinel);
|
||||
|
||||
Editing_File *file = models->working_set.files + 1;
|
||||
i32 max = models->working_set.file_max;
|
||||
for (i32 i = 0; i < max; ++i, ++file){
|
||||
dll_insert(&models->working_set.free_sentinel, &file->node);
|
||||
}
|
||||
models->working_set.array_max = 128;
|
||||
models->working_set.file_arrays = push_array(partition, File_Array, models->working_set.array_max);
|
||||
|
||||
files = push_array(partition, Editing_File, init_count);
|
||||
working_set_extend_memory(&models->working_set, files, init_count);
|
||||
|
||||
null_file = working_set_index(&models->working_set, 0);
|
||||
dll_remove(&null_file->node);
|
||||
null_file->state.is_dummy = 1;
|
||||
++models->working_set.file_count;
|
||||
|
||||
models->working_set.table.max = models->working_set.file_max * 3 / 2;
|
||||
models->working_set.table.count = 0;
|
||||
|
@ -3376,38 +3375,6 @@ App_Init_Sig(app_init){
|
|||
models->buffer_param_indices = push_array(partition, i32, models->buffer_param_max);
|
||||
}
|
||||
|
||||
internal App_Open_File_Result
|
||||
app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *working_set, String filename){
|
||||
Get_File_Result file;
|
||||
i32 file_id;
|
||||
App_Open_File_Result result = {};
|
||||
|
||||
result.file = working_set_contains(working_set, filename);
|
||||
if (result.file == 0){
|
||||
result.is_new = 1;
|
||||
file = working_set_get_available_file(working_set);
|
||||
if (file.file){
|
||||
result.file = file.file;
|
||||
file_id = exchange_request_file(exchange, 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);
|
||||
table_add(&working_set->table, result.file->name.source_path, file.index);
|
||||
|
||||
result.sys_id = file_id;
|
||||
result.file_index = file.index;
|
||||
}
|
||||
else{
|
||||
working_set_free_file(working_set, file.file);
|
||||
file.file = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
App_Step_Sig(app_step){
|
||||
ProfileStart(OS_syncing);
|
||||
Application_Step_Result app_result = *result;
|
||||
|
@ -4064,7 +4031,7 @@ App_Step_Sig(app_step){
|
|||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){
|
||||
ed_file = working_set_get_file(working_set, binding->app_id, 1).file;
|
||||
ed_file = working_set_get_active_file(working_set, binding->app_id);
|
||||
Assert(ed_file);
|
||||
|
||||
filename = exchange_file_filename(exchange, binding->sys_id);
|
||||
|
@ -4118,7 +4085,7 @@ App_Step_Sig(app_step){
|
|||
exchange_clear_file(exchange, binding->sys_id);
|
||||
}
|
||||
|
||||
Editing_File *file = working_set_get_file(working_set, binding->app_id, 1).file;
|
||||
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);
|
||||
}
|
||||
|
@ -4172,7 +4139,6 @@ App_Step_Sig(app_step){
|
|||
App_Open_File_Result result = {};
|
||||
{
|
||||
String filename = string;
|
||||
Get_File_Result file;
|
||||
i32 file_id;
|
||||
|
||||
filename.str[0] = char_to_lower(filename.str[0]);
|
||||
|
@ -4180,22 +4146,22 @@ App_Step_Sig(app_step){
|
|||
result.file = working_set_contains(working_set, filename);
|
||||
if (result.file == 0){
|
||||
result.is_new = 1;
|
||||
file = working_set_get_available_file(working_set);
|
||||
if (file.file){
|
||||
result.file = file.file;
|
||||
result.file = working_set_alloc_always(working_set, general);
|
||||
if (result.file){
|
||||
file_id = exchange_request_file(exchange, 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);
|
||||
table_add(&working_set->table, result.file->name.source_path, file.index);
|
||||
table_add(&working_set->table, result.file->name.source_path, result.file->id.id);
|
||||
|
||||
result.sys_id = file_id;
|
||||
result.file_index = file.index;
|
||||
result.file_index = result.file->id.id;
|
||||
}
|
||||
else{
|
||||
working_set_free_file(working_set, file.file);
|
||||
file.file = 0;
|
||||
working_set_free_file(working_set, result.file);
|
||||
delayed_action_repush(&models->delay2, act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4203,16 +4169,12 @@ App_Step_Sig(app_step){
|
|||
|
||||
if (result.is_new){
|
||||
if (result.file){
|
||||
if (result.sys_id){
|
||||
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{
|
||||
delayed_action_repush(&models->delay2, act);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (act->type == DACT_OPEN){
|
||||
|
@ -4257,7 +4219,7 @@ App_Step_Sig(app_step){
|
|||
if (file){
|
||||
i32 sys_id = file_save_and_set_names(system, exchange, mem, working_set, file, string.str);
|
||||
if (sys_id){
|
||||
app_push_file_binding(vars, sys_id, (i32)(file - working_set->files));
|
||||
app_push_file_binding(vars, sys_id, file->id.id);
|
||||
}
|
||||
else{
|
||||
delayed_action_repush(&models->delay2, act);
|
||||
|
@ -4284,7 +4246,7 @@ App_Step_Sig(app_step){
|
|||
if (sys_id){
|
||||
// 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, (i32)(file - working_set->files));
|
||||
app_push_file_binding(vars, sys_id, file->id.id);
|
||||
}
|
||||
else{
|
||||
delayed_action_repush(&models->delay2, act);
|
||||
|
@ -4294,18 +4256,17 @@ App_Step_Sig(app_step){
|
|||
|
||||
case DACT_NEW:
|
||||
{
|
||||
Get_File_Result file = working_set_get_available_file(working_set);
|
||||
file_create_empty(system, models, file.file, string.str);
|
||||
table_add(&working_set->table, file.file->name.source_path, file.index);
|
||||
Editing_File *file = working_set_alloc_always(working_set, general);
|
||||
file_create_empty(system, models, file, string.str);
|
||||
table_add(&working_set->table, file->name.source_path, file->id.id);
|
||||
|
||||
View *view = panel->view;
|
||||
|
||||
view_set_file(view, file.file, models, system,
|
||||
models->hooks[hook_open_file], &app_links);
|
||||
view->map = app_get_map(models, file.file->settings.base_map_id);
|
||||
view_set_file(view, file, models, system, models->hooks[hook_open_file], &app_links);
|
||||
view->map = app_get_map(models, file->settings.base_map_id);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (file.file->settings.tokens_exist)
|
||||
file_first_lex_parallel(system, general, file.file);
|
||||
if (file->settings.tokens_exist)
|
||||
file_first_lex_parallel(system, general, file);
|
||||
#endif
|
||||
}break;
|
||||
|
||||
|
|
292
4ed_file.cpp
292
4ed_file.cpp
|
@ -133,10 +133,9 @@ struct Editing_File_Preload{
|
|||
|
||||
struct Editing_File_Name{
|
||||
char live_name_[256];
|
||||
String live_name;
|
||||
|
||||
char source_path_[256];
|
||||
char extension_[16];
|
||||
String live_name;
|
||||
String source_path;
|
||||
String extension;
|
||||
};
|
||||
|
@ -145,7 +144,20 @@ struct File_Node{
|
|||
File_Node *next, *prev;
|
||||
};
|
||||
|
||||
union File_ID{
|
||||
i32 id;
|
||||
i16 part[2];
|
||||
};
|
||||
|
||||
inline File_ID
|
||||
to_file_id(i32 id){
|
||||
File_ID result;
|
||||
result.id = id;
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct Editing_File{
|
||||
// NOTE(allen): node must be the first member of Editing_File!
|
||||
File_Node node;
|
||||
Editing_File_Settings settings;
|
||||
union{
|
||||
|
@ -153,14 +165,18 @@ struct Editing_File{
|
|||
Editing_File_Preload preload;
|
||||
};
|
||||
Editing_File_Name name;
|
||||
File_ID id;
|
||||
};
|
||||
|
||||
struct File_Table_Entry{
|
||||
String name;
|
||||
u32 hash;
|
||||
i32 id;
|
||||
File_ID id;
|
||||
};
|
||||
|
||||
// TODO(allen):
|
||||
// Remove this File_Table and instead use the table in 4tech_table.cpp
|
||||
// Instead of hashing by file name use the new Unique_Hash in the system.
|
||||
struct File_Table{
|
||||
File_Table_Entry *table;
|
||||
i32 count, max;
|
||||
|
@ -186,7 +202,7 @@ table_add(File_Table *table, String name, i32 id){
|
|||
i32 i;
|
||||
|
||||
entry.name = name;
|
||||
entry.id = id;
|
||||
entry.id.id = id;
|
||||
entry.hash = get_file_hash(name);
|
||||
i = entry.hash % table->max;
|
||||
while ((e = table->table[i]).name.str){
|
||||
|
@ -221,7 +237,7 @@ table_find_pos(File_Table *table, String name, i32 *index){
|
|||
}
|
||||
|
||||
inline b32
|
||||
table_find(File_Table *table, String name, i32 *id){
|
||||
table_find(File_Table *table, String name, File_ID *id){
|
||||
i32 pos;
|
||||
b32 r = table_find_pos(table, name, &pos);
|
||||
if (r) *id = table->table[pos].id;
|
||||
|
@ -239,9 +255,16 @@ table_remove(File_Table *table, String name){
|
|||
return r;
|
||||
}
|
||||
|
||||
struct Working_Set{
|
||||
struct File_Array{
|
||||
Editing_File *files;
|
||||
i32 size;
|
||||
};
|
||||
|
||||
struct Working_Set{
|
||||
File_Array *file_arrays;
|
||||
i32 file_count, file_max;
|
||||
i16 array_count, array_max;
|
||||
|
||||
File_Node free_sentinel;
|
||||
File_Node used_sentinel;
|
||||
|
||||
|
@ -252,6 +275,167 @@ struct Working_Set{
|
|||
i32 clipboard_current, clipboard_rolling;
|
||||
};
|
||||
|
||||
internal void
|
||||
working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){
|
||||
File_ID id;
|
||||
i16 i, high_part;
|
||||
Editing_File *file_ptr;
|
||||
File_Node *free_sentinel;
|
||||
|
||||
Assert(working_set->array_count < working_set->array_max);
|
||||
|
||||
high_part = working_set->array_count++;
|
||||
working_set->file_arrays[high_part].files = new_space;
|
||||
working_set->file_arrays[high_part].size = number_of_files;
|
||||
|
||||
working_set->file_max += number_of_files;
|
||||
|
||||
id.part[1] = high_part;
|
||||
|
||||
file_ptr = new_space;
|
||||
free_sentinel = &working_set->free_sentinel;
|
||||
for (i = 0; i < number_of_files; ++i, ++file_ptr){
|
||||
id.part[0] = i;
|
||||
file_ptr->id = id;
|
||||
dll_insert(free_sentinel, &file_ptr->node);
|
||||
}
|
||||
}
|
||||
|
||||
internal Editing_File*
|
||||
working_set_alloc(Working_Set *working_set){
|
||||
Editing_File *result = 0;
|
||||
File_Node *node;
|
||||
File_ID id;
|
||||
|
||||
if (working_set->file_count < working_set->file_max){
|
||||
node = working_set->free_sentinel.next;
|
||||
Assert(node != &working_set->free_sentinel);
|
||||
result = (Editing_File*)node;
|
||||
|
||||
dll_remove(node);
|
||||
// NOTE(allen): What I really want to do here is clear everything
|
||||
// except id, but writing that out will be a pain to maintain.
|
||||
id = result->id;
|
||||
*result = {};
|
||||
result->id = id;
|
||||
dll_insert(&working_set->used_sentinel, node);
|
||||
++working_set->file_count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal Editing_File*
|
||||
working_set_alloc_always(Working_Set *working_set, General_Memory *general){
|
||||
Editing_File *result = 0;
|
||||
Editing_File *new_chunk;
|
||||
i16 new_count = 128;
|
||||
|
||||
if (working_set->file_count == working_set->file_max &&
|
||||
working_set->array_count < working_set->array_max){
|
||||
new_chunk = gen_array(general, Editing_File, new_count);
|
||||
working_set_extend_memory(working_set, new_chunk, new_count);
|
||||
}
|
||||
result = working_set_alloc(working_set);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
working_set_free_file(Working_Set *working_set, Editing_File *file){
|
||||
file->state.is_dummy = 1;
|
||||
dll_remove(&file->node);
|
||||
dll_insert(&working_set->free_sentinel, &file->node);
|
||||
--working_set->file_count;
|
||||
}
|
||||
|
||||
inline Editing_File*
|
||||
working_set_index(Working_Set *working_set, File_ID id){
|
||||
Editing_File *result = 0;
|
||||
File_Array *array;
|
||||
|
||||
if (id.part[1] >= 0 && id.part[1] < working_set->array_count){
|
||||
array = working_set->file_arrays + id.part[1];
|
||||
if (id.part[0] >= 0 && id.part[0] < array->size){
|
||||
result = array->files + id.part[0];
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline Editing_File*
|
||||
working_set_index(Working_Set *working_set, i32 id){
|
||||
Editing_File *result;
|
||||
result = working_set_index(working_set, to_file_id(id));
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline Editing_File*
|
||||
working_set_get_active_file(Working_Set *working_set, File_ID id){
|
||||
Editing_File *result = 0;
|
||||
|
||||
result = working_set_index(working_set, id);
|
||||
if (result && result->state.is_dummy){
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline Editing_File*
|
||||
working_set_get_active_file(Working_Set *working_set, i32 id){
|
||||
Editing_File *result;
|
||||
result = working_set_get_active_file(working_set, to_file_id(id));
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline Editing_File*
|
||||
working_set_contains(Working_Set *working_set, String filename){
|
||||
Editing_File *result = 0;
|
||||
File_ID id;
|
||||
|
||||
replace_char(filename, '\\', '/');
|
||||
if (table_find(&working_set->table, filename, &id)){
|
||||
result = working_set_index(working_set, id);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
// TODO(allen): Pick better first options.
|
||||
internal Editing_File*
|
||||
working_set_lookup_file(Working_Set *working_set, String string){
|
||||
Editing_File *file = 0;
|
||||
|
||||
replace_char(string, '\\', '/');
|
||||
|
||||
{
|
||||
File_Node *node, *used_nodes;
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
for (dll_items(node, used_nodes)){
|
||||
file = (Editing_File*)node;
|
||||
if (string.size == 0 || match(string, file->name.live_name)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (node == used_nodes) file = 0;
|
||||
}
|
||||
|
||||
if (!file){
|
||||
File_Node *node, *used_nodes;
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
for (dll_items(node, used_nodes)){
|
||||
file = (Editing_File*)node;
|
||||
if (string.size == 0 || has_substr(file->name.live_name, string)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (node == used_nodes) file = 0;
|
||||
}
|
||||
|
||||
return (file);
|
||||
}
|
||||
|
||||
// Hot Directory
|
||||
|
||||
struct Hot_Directory{
|
||||
|
@ -423,102 +607,6 @@ file_is_ready(Editing_File *file){
|
|||
return(result);
|
||||
}
|
||||
|
||||
inline Editing_File*
|
||||
working_set_contains(Working_Set *working, String filename){
|
||||
Editing_File *result = 0;
|
||||
i32 id;
|
||||
replace_char(filename, '\\', '/');
|
||||
if (table_find(&working->table, filename, &id)){
|
||||
if (id >= 0 && id <= working->file_max){
|
||||
result = working->files + id;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
// TODO(allen): Pick better first options.
|
||||
internal Editing_File*
|
||||
working_set_lookup_file(Working_Set *working_set, String string){
|
||||
Editing_File *file = 0;
|
||||
|
||||
replace_char(string, '\\', '/');
|
||||
|
||||
{
|
||||
File_Node *node, *used_nodes;
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
for (dll_items(node, used_nodes)){
|
||||
file = (Editing_File*)node;
|
||||
if (string.size == 0 || match(string, file->name.live_name)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (node == used_nodes) file = 0;
|
||||
}
|
||||
|
||||
if (!file){
|
||||
File_Node *node, *used_nodes;
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
for (dll_items(node, used_nodes)){
|
||||
file = (Editing_File*)node;
|
||||
if (string.size == 0 || has_substr(file->name.live_name, string)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (node == used_nodes) file = 0;
|
||||
}
|
||||
|
||||
return (file);
|
||||
}
|
||||
|
||||
struct Get_File_Result{
|
||||
Editing_File *file;
|
||||
i32 index;
|
||||
};
|
||||
|
||||
internal Get_File_Result
|
||||
working_set_get_available_file(Working_Set *working_set){
|
||||
Get_File_Result result = {};
|
||||
File_Node *node;
|
||||
|
||||
if (working_set->file_count < working_set->file_max){
|
||||
node = working_set->free_sentinel.next;
|
||||
Assert(node != &working_set->free_sentinel);
|
||||
|
||||
result.file = (Editing_File*)node;
|
||||
result.index = (i32)(result.file - working_set->files);
|
||||
|
||||
++working_set->file_count;
|
||||
|
||||
dll_remove(node);
|
||||
*result.file = {};
|
||||
dll_insert(&working_set->used_sentinel, node);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void
|
||||
working_set_free_file(Working_Set *working_set, Editing_File *file){
|
||||
file->state.is_dummy = 1;
|
||||
dll_remove(&file->node);
|
||||
dll_insert(&working_set->free_sentinel, &file->node);
|
||||
--working_set->file_count;
|
||||
}
|
||||
|
||||
inline Get_File_Result
|
||||
working_set_get_file(Working_Set *working_set, i32 id, b32 require_active){
|
||||
Get_File_Result result = {};
|
||||
if (id > 0 && id <= working_set->file_max){
|
||||
result.file = working_set->files + id;
|
||||
result.index = id;
|
||||
if (result.file->state.is_dummy && require_active){
|
||||
result.file = 0;
|
||||
result.index = 0;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_to_loading(Editing_File *file){
|
||||
file->state = {};
|
||||
|
|
|
@ -1297,7 +1297,7 @@ view_set_file(
|
|||
// Just accept it and pass the file to the open hook when it is loaded.
|
||||
if (file){
|
||||
if (open_hook && file->settings.is_initialized == 0){
|
||||
models->buffer_param_indices[models->buffer_param_count++] = (i32)(file - models->working_set.files);
|
||||
models->buffer_param_indices[models->buffer_param_count++] = file->id.id;
|
||||
open_hook(app);
|
||||
models->buffer_param_count = 0;
|
||||
file->settings.is_initialized = 1;
|
||||
|
|
|
@ -252,5 +252,9 @@ end_temp_memory(Temp_Memory temp){
|
|||
|
||||
#define reset_temp_memory end_temp_memory
|
||||
|
||||
#define gen_struct(g, T) (T*)general_memory_allocate(g, sizeof(T), 0)
|
||||
#define gen_array(g, T, size) (T*)general_memory_allocate(g, sizeof(T)*(size), 0)
|
||||
#define gen_block(g, size) general_memory_open(g, size, 0)
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -24,11 +24,6 @@ typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp);
|
|||
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory)
|
||||
typedef Sys_Set_File_List_Sig(System_Set_File_List);
|
||||
|
||||
#if 0
|
||||
#define Sys_File_Paths_Equal_Sig(name) b32 name(char *path_a, char *path_b)
|
||||
typedef Sys_File_Paths_Equal_Sig(System_File_Paths_Equal);
|
||||
#endif
|
||||
|
||||
#define Sys_File_Unique_Hash_Sig(name) Unique_Hash name(char *filename)
|
||||
typedef Sys_File_Unique_Hash_Sig(System_File_Unique_Hash);
|
||||
|
||||
|
|
|
@ -461,6 +461,25 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
}
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_File_Unique_Hash_Sig(system_file_unique_hash){
|
||||
Unique_Hash hash;
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
HANDLE handle;
|
||||
|
||||
handle = CreateFile(filename, GENERIC_READ, 0, 0,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
hash = {0};
|
||||
if (GetFileInformationByHandle(handle, &info)){
|
||||
hash.d[2] = info.dwVolumeSerialNumber;
|
||||
hash.d[1] = info.nFileIndexHigh;
|
||||
hash.d[0] = info.nFileIndexLow;
|
||||
}
|
||||
|
||||
return(hash);
|
||||
}
|
||||
|
||||
internal
|
||||
FILE_EXISTS_SIG(system_file_exists){
|
||||
char full_filename_space[1024];
|
||||
|
@ -1052,6 +1071,7 @@ Win32LoadAppCode(){
|
|||
internal void
|
||||
Win32LoadSystemCode(){
|
||||
win32vars.system->file_time_stamp = system_file_time_stamp;
|
||||
win32vars.system->file_unique_hash = system_file_unique_hash;
|
||||
win32vars.system->set_file_list = system_set_file_list;
|
||||
|
||||
win32vars.system->file_exists = system_file_exists;
|
||||
|
@ -1933,7 +1953,7 @@ main(int argc, char **argv){
|
|||
}
|
||||
|
||||
|
||||
File_Slot file_slots[32];
|
||||
File_Slot file_slots[4];
|
||||
sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
|
||||
|
||||
Font_Load_Parameters params[32];
|
||||
|
|
Loading…
Reference in New Issue