/* * Mr. 4th Dimention - Allen Webster * * 9.12.2015 * * Exchange stuff * */ // TOP 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; } 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(Exchange *exchange){ File_Exchange *files = &exchange->file; 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(Exchange *exchange, char *filename, int len){ File_Exchange *files = &exchange->file; i32 result = 0; if (len+1 < FileNameMax){ if (files->num_active < files->max){ File_Slot *file = ex__get_file(exchange); ex__set_filename(file, filename, len); file->flags |= FEx_Request; result = (int)(file - files->files) + 1; } } return result; } internal b32 exchange_file_ready(Exchange *exchange, i32 file_id, byte **data, int *size, int *max){ File_Exchange *files = &exchange->file; b32 result = 0; if (file_id > 0 && file_id <= files->max){ File_Slot *file = files->files + file_id - 1; if (file->flags & FEx_Ready){ *data = file->data; *size = file->size; *max = file->max; result = 1; } if (file->flags & FEx_Not_Exist){ *data = 0; *size = 0; *max = 0; result = 1; } } return result; } internal b32 exchange_file_does_not_exist(Exchange *exchange, i32 file_id){ File_Exchange *files = &exchange->file; 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(Exchange *exchange, char *filename, int len, byte *data, int size, int max){ File_Exchange *files = &exchange->file; i32 result = 0; if (len+1 < FileNameMax){ if (files->num_active < files->max){ File_Slot *file = ex__get_file(exchange); 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(Exchange *exchange, i32 file_id, byte **data, int *size, int *max, int *failed){ File_Exchange *files = &exchange->file; 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(Exchange *exchange, i32 file_id, i32 *size = 0){ File_Exchange *files = &exchange->file; 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(Exchange *exchange, i32 file_id){ File_Exchange *files = &exchange->file; 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(Exchange *exchange, i32 file_id){ File_Exchange *files = &exchange->file; if (file_id > 0 && file_id <= files->max){ File_Slot *file = files->files + file_id - 1; ex__clear(file); } } internal b32 queue_job_is_pending(Work_Queue *queue, u32 job_id){ b32 result; u32 job_index; Full_Job_Data *full_job; job_index = job_id % QUEUE_WRAP; full_job = queue->jobs + job_index; Assert(full_job->id == job_id); result = 0; if (full_job->running_thread != 0){ result = 1; } return(result); } // BOTTOM