started switching file tracking over to an integrated subsystem

master
Allen Webster 2017-03-18 17:07:25 -04:00
parent 3edcf0a5b3
commit 2b2e90c987
7 changed files with 210 additions and 326 deletions

View File

@ -275,70 +275,6 @@ eol_in_place_convert_out(char *data, i32 size, i32 max, i32 *size_out){
//////////////////////////////////////
// TODO(allen): ditch this shit yo
inline i32
is_whitespace(char c){
i32 result;
result = (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\f' || c == '\v');
return(result);
}
inline i32
is_alphanumeric_true(char c){
return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9');
}
inline i32
is_alphanumeric(char c){
return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_');
}
inline i32
is_upper(char c){
return (c >= 'A' && c <= 'Z');
}
inline i32
is_lower(char c){
return (c >= 'a' && c <= 'z');
}
inline char
to_upper(char c){
if (is_lower(c)){
c += 'A' - 'a';
}
return(c);
}
internal i32
is_match(char *a, char *b, i32 len){
i32 result = 1;
for (;len > 0; --len, ++a, ++b){
if (*a != *b){
result = 0;
break;
}
}
return(result);
}
internal i32
is_match_insensitive(char *a, char *b, i32 len){
i32 result = 1;
for (;len > 0; --len, ++a, ++b){
if (to_upper(*a) != to_upper(*b)){
result = 0;
break;
}
}
return(result);
}
//////////////////////////////////////
//
// Implementation of the gap buffer
//

View File

@ -1,27 +1,26 @@
/*
Copy Right FourTech LLC, 2016
All Rights Are Reserved
The OS agnostic file tracking API for applications
that want to interact with potentially many files on
the disk that could be changed by other applications.
Created on: 20.07.2016
*/
* Mr. 4th Dimention - Allen Webster
*
* 20.07.2016
*
* File tracking API.
*
*/
// TOP
#ifndef FILE_TRACK_4TECH_H
#if !defined(FILE_TRACK_4TECH_H)
#define FILE_TRACK_4TECH_H
#ifndef FILE_TRACK_LINK
#define FILE_TRACK_LINK static
#if !defined(FILE_TRACK_LINK)
# define FILE_TRACK_LINK static
#endif
#include <stdint.h>
typedef struct{
u8 opaque[128];
} File_Track_System;
typedef i32 File_Track_Result;
enum{
FileTrack_Good,
FileTrack_MemoryTooSmall,
@ -31,16 +30,8 @@ enum{
FileTrack_FileSystemError
};
typedef struct{
uint8_t opaque[128];
} File_Track_System;
typedef int32_t File_Track_Result;
FILE_TRACK_LINK File_Track_Result
init_track_system(File_Track_System *system,
void *table_memory, int32_t table_memory_size,
void *listener_memory, int32_t listener_memory_size);
init_track_system(File_Track_System *system, void *table_memory, i32 table_memory_size, void *listener_memory, i32 listener_memory_size);
FILE_TRACK_LINK File_Track_Result
add_listener(File_Track_System *system, char *filename);
@ -49,13 +40,13 @@ FILE_TRACK_LINK File_Track_Result
remove_listener(File_Track_System *system, char *filename);
FILE_TRACK_LINK File_Track_Result
move_track_system(File_Track_System *system, void *mem, int32_t size);
move_track_system(File_Track_System *system, void *mem, i32 size);
FILE_TRACK_LINK File_Track_Result
expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size);
expand_track_system_listeners(File_Track_System *system, void *mem, i32 size);
FILE_TRACK_LINK File_Track_Result
get_change_event(File_Track_System *system, char *buffer, int32_t max);
get_change_event(File_Track_System *system, u8 *buffer, i32 max);
FILE_TRACK_LINK File_Track_Result
shut_down_track_system(File_Track_System *system);

View File

@ -1,45 +1,33 @@
/*
Copy Right FourTech LLC, 2016
All Rights Are Reserved
The OS agnostic file tracking API for applications
that want to interact with potentially many files on
the disk that could be changed by other applications.
Created on: 27.08.2016
*/
* Mr. 4th Dimention - Allen Webster
*
* 20.08.2016
*
* File tracking shared.
*
*/
// TOP
#ifndef Assert
# define Assert(c) do { if (!(c)) { *((int*)0) = 0xA11E; } } while (0)
#endif
#ifndef ZeroStruct
# define ZeroStruct(s) for (int32_t i = 0; i < sizeof(s); ++i) { ((char*)(&(s)))[i] = 0; }
#endif
typedef struct{
uint32_t id[4];
u32 id[4];
} File_Index;
typedef uint32_t rptr32;
typedef u32 rptr32;
#define to_ptr(b,p) ((void*)((char*)b + p))
#define to_rptr32(b,p) ((rptr32)((char*)(p) - (char*)(b)))
typedef struct {
File_Index hash;
uint32_t opaque[4];
u32 opaque[4];
} File_Track_Entry;
global_const File_Track_Entry null_file_track_entry = {0};
typedef struct {
int32_t size;
uint32_t tracked_count;
uint32_t max;
i32 size;
u32 tracked_count;
u32 max;
rptr32 file_table;
} File_Track_Tables;
@ -50,13 +38,13 @@ typedef struct DLL_Node {
static File_Index
internal File_Index
zero_file_index(){
File_Index a = {0};
return(a);
}
static int32_t
internal i32
file_hash_is_zero(File_Index a){
return ((a.id[0] == 0) &&
(a.id[1] == 0) &&
@ -64,7 +52,7 @@ file_hash_is_zero(File_Index a){
(a.id[3] == 0));
}
static int32_t
internal i32
file_hash_is_deleted(File_Index a){
return ((a.id[0] == 0xFFFFFFFF) &&
(a.id[1] == 0xFFFFFFFF) &&
@ -72,7 +60,7 @@ file_hash_is_deleted(File_Index a){
(a.id[3] == 0xFFFFFFFF));
}
static int32_t
internal i32
file_index_eq(File_Index a, File_Index b){
return ((a.id[0] == b.id[0]) &&
(a.id[1] == b.id[1]) &&
@ -80,7 +68,7 @@ file_index_eq(File_Index a, File_Index b){
(a.id[3] == b.id[3]));
}
static void
internal void
insert_node(DLL_Node *pos, DLL_Node *node){
node->prev = pos;
node->next = pos->next;
@ -88,19 +76,19 @@ insert_node(DLL_Node *pos, DLL_Node *node){
node->next->prev = node;
}
static void
internal void
remove_node(DLL_Node *node){
node->next->prev = node->prev;
node->prev->next = node->next;
}
static void
internal void
init_sentinel_node(DLL_Node *node){
node->next = node;
node->prev = node;
}
static DLL_Node*
internal DLL_Node*
allocate_node(DLL_Node *sentinel){
DLL_Node *result = 0;
if (sentinel->next != sentinel){
@ -113,17 +101,17 @@ allocate_node(DLL_Node *sentinel){
#define FILE_ENTRY_COST (sizeof(File_Track_Entry))
static int32_t
tracking_system_has_space(File_Track_Tables *tables, int32_t new_count){
uint32_t count = tables->tracked_count;
uint32_t max = tables->max;
int32_t result = ((count + new_count)*8 < max*7);
internal i32
tracking_system_has_space(File_Track_Tables *tables, i32 new_count){
u32 count = tables->tracked_count;
u32 max = tables->max;
i32 result = ((count + new_count)*8 < max*7);
return(result);
}
static int32_t
internal i32
entry_is_available(File_Track_Entry *entry){
int32_t result = 0;
i32 result = 0;
if (entry){
result =
file_hash_is_zero(entry->hash) ||
@ -132,12 +120,12 @@ entry_is_available(File_Track_Entry *entry){
return (result);
}
static File_Track_Entry*
internal File_Track_Entry*
tracking_system_lookup_entry(File_Track_Tables *tables, File_Index key){
uint32_t hash = key.id[0];
uint32_t max = tables->max;
uint32_t index = (hash) % max;
uint32_t start = index;
u32 hash = key.id[0];
u32 max = tables->max;
u32 index = (hash) % max;
u32 start = index;
File_Track_Entry *entries = (File_Track_Entry*)to_ptr(tables, tables->file_table);
@ -169,7 +157,7 @@ tracking_system_lookup_entry(File_Track_Tables *tables, File_Index key){
return(result);
}
static File_Track_Entry*
internal File_Track_Entry*
get_file_entry(File_Track_Tables *tables, File_Index index){
File_Track_Entry *entry = 0;
@ -181,11 +169,11 @@ get_file_entry(File_Track_Tables *tables, File_Index index){
return(entry);
}
static void
internal void
internal_free_slot(File_Track_Tables *tables, File_Track_Entry *entry){
Assert(!entry_is_available(entry));
ZeroStruct(*entry);
*entry = null_file_track_entry;
entry->hash.id[0] = 0xFFFFFFFF;
entry->hash.id[1] = 0xFFFFFFFF;
entry->hash.id[2] = 0xFFFFFFFF;
@ -194,27 +182,26 @@ internal_free_slot(File_Track_Tables *tables, File_Track_Entry *entry){
--tables->tracked_count;
}
static int32_t
enough_memory_to_init_table(int32_t table_memory_size){
int32_t result = (sizeof(File_Track_Tables) + FILE_ENTRY_COST*8 <= table_memory_size);
internal i32
enough_memory_to_init_table(i32 table_memory_size){
i32 result = (sizeof(File_Track_Tables) + FILE_ENTRY_COST*8 <= table_memory_size);
return(result);
}
static void
init_table_memory(File_Track_Tables *tables, int32_t table_memory_size){
internal void
init_table_memory(File_Track_Tables *tables, i32 table_memory_size){
tables->size = table_memory_size;
tables->tracked_count = 0;
int32_t max_number_of_entries =
(table_memory_size - sizeof(*tables)) / FILE_ENTRY_COST;
i32 max_number_of_entries = (table_memory_size - sizeof(*tables)) / FILE_ENTRY_COST;
tables->file_table = sizeof(*tables);
tables->max = max_number_of_entries;
}
static File_Track_Result
internal File_Track_Result
move_table_memory(File_Track_Tables *original_tables,
void *mem, int32_t size){
void *mem, i32 size){
File_Track_Result result = FileTrack_Good;
if (original_tables->size < size){
@ -224,24 +211,22 @@ move_table_memory(File_Track_Tables *original_tables,
{
tables->size = size;
int32_t likely_entry_size = FILE_ENTRY_COST;
int32_t max_number_of_entries = (size - sizeof(*tables)) / likely_entry_size;
i32 likely_entry_size = FILE_ENTRY_COST;
i32 max_number_of_entries = (size - sizeof(*tables)) / likely_entry_size;
tables->file_table = sizeof(*tables);
tables->max = max_number_of_entries;
}
if (tables->max > original_tables->max){
uint32_t original_max = original_tables->max;
u32 original_max = original_tables->max;
// NOTE(allen): Rehash the tracking table
{
File_Track_Entry *entries = (File_Track_Entry*)
to_ptr(original_tables, original_tables->file_table);
for (uint32_t index = 0;
index < original_max;
++index){
for (u32 index = 0; index < original_max; ++index){
File_Track_Entry *entry = entries + index;
if (!entry_is_available(entry)){
File_Index hash = entry->hash;
@ -267,4 +252,5 @@ move_table_memory(File_Track_Tables *original_tables,
return(result);
}
// BOTTOM
// BOTTOM

View File

@ -1,17 +1,15 @@
/*
The OS agnostic file tracking API for applications
that want to interact with potentially many files on
the disk that could be changed by other applications.
Created on: 20.07.2016
*/
* Mr. 4th Dimention - Allen Webster
*
* 20.07.2016
*
* File tracking win32.
*
*/
// TOP
#include "4tech_file_track.h"
#include "4tech_file_track_general.c"
#include "4ed_file_track.h"
#include <Windows.h>
@ -19,8 +17,9 @@ typedef struct {
OVERLAPPED overlapped;
char result[2048];
HANDLE dir;
int32_t user_count;
i32 user_count;
} Win32_Directory_Listener;
global_const OVERLAPPED null_overlapped = {0};
typedef struct {
DLL_Node node;
@ -44,9 +43,7 @@ typedef struct {
#define to_tables(v) ((File_Track_Tables*)(v->tables))
FILE_TRACK_LINK File_Track_Result
init_track_system(File_Track_System *system,
void *table_memory, int32_t table_memory_size,
void *listener_memory, int32_t listener_memory_size){
init_track_system(File_Track_System *system, void *table_memory, i32 table_memory_size, void *listener_memory, i32 listener_memory_size){
File_Track_Result result = FileTrack_MemoryTooSmall;
Win32_File_Track_Vars *vars = to_vars(system);
@ -65,8 +62,8 @@ init_track_system(File_Track_System *system,
init_sentinel_node(&vars->free_sentinel);
Win32_Directory_Listener_Node *listener = (Win32_Directory_Listener_Node*)listener_memory;
int32_t count = listener_memory_size / sizeof(Win32_Directory_Listener_Node);
for (int32_t i = 0; i < count; ++i, ++listener){
i32 count = listener_memory_size / sizeof(Win32_Directory_Listener_Node);
for (i32 i = 0; i < count; ++i, ++listener){
insert_node(&vars->free_sentinel, &listener->node);
}
}
@ -83,22 +80,19 @@ init_track_system(File_Track_System *system,
return(result);
}
static int32_t
internal_get_parent_name(char *out, int32_t max, char *name){
int32_t len, slash_i;
internal i32
internal_get_parent_name(char *out, i32 max, char *name){
char *ptr = name;
for (; *ptr != 0; ++ptr);
len = (int32_t)(ptr - name);
i32 len = (i32)(ptr - name);
// TODO(allen): make this system real
Assert(len < max);
for (slash_i = len-1;
slash_i > 0 && name[slash_i] != '\\' && name[slash_i] != '/';
--slash_i);
i32 slash_i = len-1;
for (;slash_i > 0 && name[slash_i] != '\\' && name[slash_i] != '/';--slash_i);
for (int32_t i = 0; i < slash_i; ++i){
for (i32 i = 0; i < slash_i; ++i){
out[i] = name[i];
}
out[slash_i] = 0;
@ -106,7 +100,7 @@ internal_get_parent_name(char *out, int32_t max, char *name){
return(slash_i);
}
static File_Index
internal File_Index
internal_get_file_index(BY_HANDLE_FILE_INFORMATION info){
File_Index hash;
hash.id[0] = info.nFileIndexLow;
@ -157,7 +151,7 @@ add_listener(File_Track_System *system, char *filename){
allocate_node(&vars->free_sentinel);
if (node){
if (CreateIoCompletionPort(dir, vars->iocp, (ULONG_PTR)node, 1)){
ZeroStruct(node->listener.overlapped);
node->listener.overlapped = null_overlapped;
if (ReadDirectoryChangesW(dir, node->listener.result, sizeof(node->listener.result), 1, FLAGS, 0, &node->listener.overlapped, 0)){
node->listener.dir = dir;
node->listener.user_count = 1;
@ -216,51 +210,42 @@ remove_listener(File_Track_System *system, char *filename){
EnterCriticalSection(&vars->table_lock);
{
File_Track_Tables *tables = to_tables(vars);
File_Track_Tables *tables = to_tables(vars);
// TODO(allen): make this real!
char dir_name[1024];
internal_get_parent_name(dir_name, sizeof(dir_name), filename);
HANDLE dir = CreateFile(dir_name, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
if (dir != INVALID_HANDLE_VALUE){
BY_HANDLE_FILE_INFORMATION dir_info = {0};
DWORD getinfo_result = GetFileInformationByHandle(dir, &dir_info);
// TODO(allen): make this real!
char dir_name[1024];
internal_get_parent_name(dir_name, sizeof(dir_name), filename);
HANDLE dir = CreateFile(
dir_name,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
0);
if (dir != INVALID_HANDLE_VALUE){
BY_HANDLE_FILE_INFORMATION dir_info = {0};
DWORD getinfo_result = GetFileInformationByHandle(dir, &dir_info);
if (getinfo_result){
File_Index dir_hash = internal_get_file_index(dir_info);
File_Track_Entry *dir_lookup = tracking_system_lookup_entry(tables, dir_hash);
Win32_File_Track_Entry *win32_dir = (Win32_File_Track_Entry*)dir_lookup;
if (getinfo_result){
File_Index dir_hash = internal_get_file_index(dir_info);
File_Track_Entry *dir_lookup = tracking_system_lookup_entry(tables, dir_hash);
Win32_File_Track_Entry *win32_dir = (Win32_File_Track_Entry*)dir_lookup;
Assert(!entry_is_available(dir_lookup));
Win32_Directory_Listener_Node *node = win32_dir->listener_node;
--node->listener.user_count;
if (node->listener.user_count == 0){
insert_node(&vars->free_sentinel, &node->node);
CancelIo(win32_dir->dir);
CloseHandle(win32_dir->dir);
internal_free_slot(tables, dir_lookup);
}
}
else{
result = FileTrack_FileSystemError;
}
Assert(!entry_is_available(dir_lookup));
Win32_Directory_Listener_Node *node = win32_dir->listener_node;
--node->listener.user_count;
CloseHandle(dir);
if (node->listener.user_count == 0){
insert_node(&vars->free_sentinel, &node->node);
CancelIo(win32_dir->dir);
CloseHandle(win32_dir->dir);
internal_free_slot(tables, dir_lookup);
}
}
else{
result = FileTrack_FileSystemError;
}
CloseHandle(dir);
}
else{
result = FileTrack_FileSystemError;
}
LeaveCriticalSection(&vars->table_lock);
@ -269,17 +254,15 @@ remove_listener(File_Track_System *system, char *filename){
}
FILE_TRACK_LINK File_Track_Result
move_track_system(File_Track_System *system, void *mem, int32_t size){
move_track_system(File_Track_System *system, void *mem, i32 size){
File_Track_Result result = FileTrack_Good;
Win32_File_Track_Vars *vars = to_vars(system);
EnterCriticalSection(&vars->table_lock);
{
File_Track_Tables *original_tables = to_tables(vars);
result = move_table_memory(original_tables, mem, size);
if (result == FileTrack_Good){
vars->tables = mem;
}
File_Track_Tables *original_tables = to_tables(vars);
result = move_table_memory(original_tables, mem, size);
if (result == FileTrack_Good){
vars->tables = mem;
}
LeaveCriticalSection(&vars->table_lock);
@ -287,7 +270,7 @@ move_track_system(File_Track_System *system, void *mem, int32_t size){
}
FILE_TRACK_LINK File_Track_Result
expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size){
expand_track_system_listeners(File_Track_System *system, void *mem, i32 size){
File_Track_Result result = FileTrack_Good;
Win32_File_Track_Vars *vars = to_vars(system);
@ -295,8 +278,8 @@ expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size
if (sizeof(Win32_Directory_Listener_Node) <= size){
Win32_Directory_Listener_Node *listener = (Win32_Directory_Listener_Node*)mem;
int32_t count = size / sizeof(Win32_Directory_Listener_Node);
for (int32_t i = 0; i < count; ++i, ++listener){
i32 count = size / sizeof(Win32_Directory_Listener_Node);
for (i32 i = 0; i < count; ++i, ++listener){
insert_node(&vars->free_sentinel, &listener->node);
}
}
@ -310,99 +293,84 @@ expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size
}
FILE_TRACK_LINK File_Track_Result
get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *size){
get_change_event(File_Track_System *system, char *buffer, i32 max, i32 *size){
File_Track_Result result = FileTrack_NoMoreEvents;
Win32_File_Track_Vars *vars = to_vars(system);
static int32_t has_buffered_event = 0;
static DWORD offset = 0;
static Win32_Directory_Listener listener;
local_persist i32 has_buffered_event = 0;
local_persist DWORD offset = 0;
local_persist Win32_Directory_Listener listener;
EnterCriticalSection(&vars->table_lock);
{
OVERLAPPED *overlapped = 0;
DWORD length = 0;
ULONG_PTR key = 0;
int32_t has_result = 0;
if (has_buffered_event){
has_buffered_event = 0;
OVERLAPPED *overlapped = 0;
DWORD length = 0;
ULONG_PTR key = 0;
i32 has_result = 0;
if (has_buffered_event){
has_buffered_event = 0;
has_result = 1;
}
else{
if (GetQueuedCompletionStatus(vars->iocp, &length, &key, &overlapped, 0)){
Win32_Directory_Listener *listener_ptr = (Win32_Directory_Listener*)overlapped;
// NOTE(allen): Get a copy of the state of this node so we can set the node
// to work listening for changes again right away.
listener = *listener_ptr;
listener_ptr->overlapped = null_overlapped;
ReadDirectoryChangesW(listener_ptr->dir, listener_ptr->result, sizeof(listener_ptr->result), 1, FLAGS, 0, &listener_ptr->overlapped, 0);
offset = 0;
has_result = 1;
}
else{
if (GetQueuedCompletionStatus(vars->iocp,
&length,
&key,
&overlapped,
0)){
Win32_Directory_Listener *listener_ptr = (Win32_Directory_Listener*)overlapped;
// NOTE(allen): Get a copy of the state of this node so we can set the node
// to work listening for changes again right away.
listener = *listener_ptr;
ZeroStruct(listener_ptr->overlapped);
ReadDirectoryChangesW(listener_ptr->dir,
listener_ptr->result,
sizeof(listener_ptr->result),
1,
FLAGS,
0,
&listener_ptr->overlapped,
0);
offset = 0;
has_result = 1;
}
if (has_result){
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*)(listener.result + offset);
i32 len = info->FileNameLength / 2;
i32 dir_len = GetFinalPathNameByHandle(listener.dir, 0, 0, FILE_NAME_NORMALIZED);
i32 req_size = dir_len + 1 + len;
*size = req_size;
if (req_size < max){
i32 pos = 0;
pos = GetFinalPathNameByHandle(listener.dir, buffer, max, FILE_NAME_NORMALIZED);
buffer[pos++] = '\\';
for (i32 i = 0; i < len; ++i, ++pos){
buffer[pos] = (char)info->FileName[i];
}
if (buffer[0] == '\\'){
for (i32 i = 0; i+4 < pos; ++i){
buffer[i] = buffer[i+4];
}
*size -= 4;
}
result = FileTrack_Good;
}
else{
// TODO(allen): Need some way to stash this result so that if the
// user comes back with more memory we can give them the change
// notification they missed.
result = FileTrack_MemoryTooSmall;
}
if (has_result){
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*)(listener.result + offset);
int32_t len = info->FileNameLength / 2;
int32_t dir_len = GetFinalPathNameByHandle(listener.dir, 0, 0,
FILE_NAME_NORMALIZED);
int32_t req_size = dir_len + 1 + len;
*size = req_size;
if (req_size < max){
int32_t pos = 0;
pos = GetFinalPathNameByHandle(listener.dir, buffer, max,
FILE_NAME_NORMALIZED);
buffer[pos++] = '\\';
for (int32_t i = 0; i < len; ++i, ++pos){
buffer[pos] = (char)info->FileName[i];
}
if (buffer[0] == '\\'){
for (int32_t i = 0; i+4 < pos; ++i){
buffer[i] = buffer[i+4];
}
*size -= 4;
}
result = FileTrack_Good;
}
else{
// TODO(allen): Need some way to stash this result so that if the
// user comes back with more memory we can give them the change
// notification they missed.
result = FileTrack_MemoryTooSmall;
}
if (info->NextEntryOffset != 0){
// TODO(allen): We're not ready to handle this yet.
// For now I am breaking. In the future, if there
// are more results we should stash them and return
// them in future calls.
offset += info->NextEntryOffset;
has_buffered_event = 1;
}
if (info->NextEntryOffset != 0){
// TODO(allen): We're not ready to handle this yet.
// For now I am breaking. In the future, if there
// are more results we should stash them and return
// them in future calls.
offset += info->NextEntryOffset;
has_buffered_event = 1;
}
}
@ -423,9 +391,9 @@ shut_down_track_system(File_Track_System *system){
File_Track_Tables *tables = to_tables(vars);
File_Track_Entry *entries = (File_Track_Entry*)to_ptr(tables, tables->file_table);
uint32_t max = tables->max;
u32 max = tables->max;
for (uint32_t index = 0; index < max; ++index){
for (u32 index = 0; index < max; ++index){
File_Track_Entry *entry = entries + index;
if (!entry_is_available(entry)){

View File

@ -1113,9 +1113,7 @@ wrap_state_consume_token(System_Functions *system, Render_Font *font, Code_Wrap_
end = fixed_end_point;
}
if (i < line_start){
i = line_start;
}
i = clamp_top(i, line_start);
if (i == line_start){
skipping_whitespace = true;

View File

@ -28,6 +28,12 @@
// Program setup
//
#define SUPPORT_DPI 1
#define UNICODE
#define FPS 60
#define frame_useconds (1000000 / FPS)
#include <assert.h>
#include <string.h>
#include "4tech_defines.h"
@ -63,21 +69,20 @@
#define GL_TEXTURE_MAX_LEVEL 0x813D
#include "filetrack/4tech_file_track_win32.c"
//////////////////////////////
#include "4ed_file_track.h"
#include "4ed_system_shared.h"
#define SUPPORT_DPI 1
#define FPS 60
#define frame_useconds (1000000 / FPS)
#define WM_4coder_ANIMATE (WM_USER + 0)
#include "4ed_file_track_general.cpp"
#include "4ed_file_track_win32.cpp"
//
// Win32_Vars structs
//
#define WM_4coder_ANIMATE (WM_USER + 0)
struct Thread_Context{
u32 job_id;
b32 running;