windows unique file hash

This commit is contained in:
Allen Webster 2016-03-08 18:06:27 -05:00
parent b343a1c4ae
commit 5538468eab
7 changed files with 298 additions and 230 deletions

View File

@ -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
View File

@ -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;

View File

@ -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 = {};

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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];