This commit is contained in:
Allen Webster 2017-03-18 17:39:15 -04:00
commit 49d1f490d1
17 changed files with 332 additions and 403 deletions

View File

@ -35,24 +35,25 @@
#include "4ed_rendering.h"
#include "4ed.h"
#include "4ed_buffer_model.h"
#define FCPP_FORBID_MALLOC
#include "4cpp/4cpp_lexer.h"
#include "4ed_doubly_linked_list.cpp"
#include "4ed_font_set.cpp"
#include "4ed_translation.cpp"
#include "4ed_rendering_helper.cpp"
#include "4ed_style.h"
#include "4ed_style.cpp"
#include "4ed_command.cpp"
#include "file/4coder_buffer.cpp"
#include "file/4coder_undo.cpp"
#include "file/4coder_file.cpp"
#include "file/4coder_working_set.cpp"
#include "file/4coder_hot_directory.cpp"
#include "4ed_buffer.cpp"
#include "4ed_undo.cpp"
#include "4ed_file.cpp"
#include "4ed_working_set.cpp"
#include "4ed_hot_directory.cpp"
#include "4ed_gui.h"
#include "4ed_gui.cpp"

View File

@ -13,8 +13,8 @@
// Buffer low level operations
//
#include "../font/4coder_font_data.h"
#include "../4coder_helper/4coder_seek_types.h"
#include "font/4coder_font_data.h"
#include "4coder_helper/4coder_seek_types.h"
typedef struct Cursor_With_Index{
i32 pos;
@ -186,6 +186,8 @@ buffer_batch_edit_update_cursors(Cursor_With_Index *sorted_positions, i32 count,
return(shift_amount);
}
//////////////////////////////////////
internal i32
eol_convert_in(char *dest, char *src, i32 size){
i32 i = 0, j = 0, k = 0;
@ -271,80 +273,7 @@ eol_in_place_convert_out(char *data, i32 size, i32 max, i32 *size_out){
return(result);
}
// 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);
}
struct Buffer_Model_Step{
u32 type;
u32 value;
i32 i;
u32 byte_length;
};
struct Buffer_Model_Behavior{
b32 do_newline;
b32 do_codepoint_advance;
b32 do_number_advance;
};
enum{
BufferModelUnit_None,
BufferModelUnit_Codepoint,
BufferModelUnit_Numbers,
};
#include "4coder_translation.cpp"
//////////////////////////////////////
//
// Implementation of the gap buffer
@ -409,31 +338,30 @@ buffer_init_provide_page(Gap_Buffer_Init *init, void *page, i32 page_size){
buffer->max = page_size;
}
internal i32
internal b32
buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){
Gap_Buffer *buffer = init->buffer;
i32 osize1 = 0, size1 = 0, size2 = 0, size = init->size;
i32 result = 0;
b32 result = false;
if (buffer->data){
if (buffer->max >= init->size){
size2 = size >> 1;
size1 = osize1 = size - size2;
if (size1 > 0){
size1 = eol_convert_in(buffer->data, init->data, size1);
if (size2 > 0){
size2 = eol_convert_in(buffer->data + size1, init->data + osize1, size2);
}
if (buffer->data && buffer->max >= init->size){
i32 size = init->size;
i32 size2 = size >> 1;
i32 osize1 = size - size2;
i32 size1 = osize1;
if (size1 > 0){
size1 = eol_convert_in(buffer->data, init->data, size1);
if (size2 > 0){
size2 = eol_convert_in(buffer->data + size1, init->data + osize1, size2);
}
buffer->size1 = size1;
buffer->size2 = size2;
buffer->gap_size = buffer->max - size1 - size2;
memmove(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2);
result = 1;
}
buffer->size1 = size1;
buffer->size2 = size2;
buffer->gap_size = buffer->max - size1 - size2;
memmove(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2);
result = true;
}
return(result);
@ -771,7 +699,7 @@ buffer_measure_character_starts(System_Functions *system, Render_Font *font, Gap
translating_fully_process_byte(system, font, &tran, ch, i, size, &emits);
for (TRANSLATION_DECL_OUTPUT(J, emits)){
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, J, emits);
if (behavior.do_newline){
@ -898,7 +826,7 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para
translating_fully_process_byte(params.system, params.font, &S.tran, ch, S.i, S.size, &S.emits);
}
for (TRANSLATION_OUTPUT(S.J, S.emits)){
for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){
TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits);
if (S.behavior.do_newline){
@ -1107,7 +1035,7 @@ buffer_remeasure_character_starts(System_Functions *system, Render_Font *font, G
u8 ch = (u8)stream.data[char_i];
translating_fully_process_byte(system, font, &tran, ch, char_i, size, &emits);
for (TRANSLATION_DECL_OUTPUT(J, emits)){
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, J, emits);
if (behavior.do_newline){
@ -1582,7 +1510,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa
translating_fully_process_byte(params.system, params.font, &S.tran, ch, S.i, S.size, &S.emits);
}
for (TRANSLATION_OUTPUT(S.J, S.emits)){
for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){
TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits);
S.prev_cursor = S.this_cursor;
@ -1945,7 +1873,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32
translating_fully_process_byte(params.system, params.font, &S.tran, ch, S.i, S.size, &S.emits);
}
for (TRANSLATION_OUTPUT(S.J, S.emits)){
for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){
TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits);
if (!S.behavior.do_newline && S.step.i >= S.wrap_unit_end){

37
4ed_buffer_model.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 18.03.2017
*
* Abstract model for the describing the characters of a buffer.
*
*/
// TOP
#if !defined(FRED_BUFFER_MODEL_H)
#define FRED_BUFFER_MODEL_H
struct Buffer_Model_Step{
u32 type;
u32 value;
i32 i;
u32 byte_length;
};
struct Buffer_Model_Behavior{
b32 do_newline;
b32 do_codepoint_advance;
b32 do_number_advance;
};
enum{
BufferModelUnit_None,
BufferModelUnit_Codepoint,
BufferModelUnit_Numbers,
};
#endif
// BOTTOM

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;
b32 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;
@ -1132,7 +1130,7 @@ wrap_state_consume_token(System_Functions *system, Render_Font *font, Code_Wrap_
u8 ch = (u8)state->stream.data[i];
translating_fully_process_byte(system, font, &state->tran, ch, i, state->size, &state->emits);
for (TRANSLATION_OUTPUT(state->J, state->emits)){
for (TRANSLATION_EMIT_LOOP(state->J, state->emits)){
TRANSLATION_GET_STEP(state->step, state->behavior, state->J, state->emits);
if (state->behavior.do_newline){
@ -4767,15 +4765,15 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
u32 total_count = system->font.get_count();
u32 count = Min(total_count, 10);
for (u32 font_index = 1; font_index < count; ++font_index){
for (u32 font_index = 0; font_index < count; ++font_index){
Font_ID this_font_id = 0;
system->font.get_ids_by_index(font_index, 1, &font_id);
system->font.get_ids_by_index(font_index, 1, &this_font_id);
char name_space[256];
String name = make_fixed_width_string(name_space);
name.size = system->font.get_name_by_index(font_index, name.str, name.memory_size);
id.id[0] = (u64)this_font_id;
id.id[0] = (u64)font_index + 1;
if (this_font_id != font_id){
if (gui_do_font_button(target, id, this_font_id, name)){
new_font_id = this_font_id;

View File

@ -1,13 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 18.12.2015
*
* Font set for 4coder
*
*/
// TOP
// BOTTOM

View File

@ -139,10 +139,46 @@ draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_i
x = (f32)x_;
f32 byte_advance = font_get_byte_advance(font);
f32 *sub_advances = font_get_byte_sub_advances(font);
u8 *str = (u8*)str_.str;
u8 *str_end = str + str_.size;
Translation_State tran = {0};
Translation_Emits emits = {0};
for (u32 i = 0; str < str_end; ++str, ++i){
translating_fully_process_byte(system, font, &tran, *str, i, str_.size, &emits);
for (TRANSLATION_DECL_EMIT_LOOP(j, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, j, emits);
if (behavior.do_codepoint_advance){
u32 codepoint = step.value;
if (color != 0){
font_draw_glyph(target, font_id, type, codepoint, x, y, color);
}
x += font_get_glyph_advance(system, font, codepoint);
}
else if (behavior.do_number_advance){
u8 n = (u8)(step.value);
if (color != 0){
u8 cs[3];
cs[0] = '\\';
byte_to_ascii(n, cs+1);
f32 xx = x;
for (u32 j = 0; j < 3; ++j){
font_draw_glyph(target, font_id, type, cs[j], xx, y, color);
xx += sub_advances[j];
}
}
x += byte_advance;
}
}
}
#if 0
for (;str < str_end;){
u8 *byte = str;
u32 codepoint = utf8_to_u32(&str, str_end);
@ -188,6 +224,7 @@ draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_i
}
}
}
#endif
}
return(x);

View File

@ -9,6 +9,8 @@
// TOP
#include "4ed_buffer_model.h"
struct Translation_State{
u8 fill_buffer[4];
u32 fill_start_i;
@ -196,17 +198,6 @@ translating_generate_emits(Translation_State *tran, Translation_Emit_Rule emit_r
skip_all:;
}
#if 0
internal void
translating_fully_process_byte(Translation_State *tran, u8 ch, u32 i, u32 size, Translation_Emits *emits_out){
Translation_Byte_Description description = {0};
translating_consume_byte(tran, ch, i, size, &description);
Translation_Emit_Rule emit_rule = {0};
translating_select_emit_rule_ASCII(tran, description, &emit_rule);
translating_generate_emits(tran, emit_rule, ch, i, emits_out);
}
#endif
internal void
translating_fully_process_byte(System_Functions *system, Render_Font *font, Translation_State *tran, u8 ch, u32 i, u32 size, Translation_Emits *emits_out){
Translation_Byte_Description description = {0};
@ -238,12 +229,12 @@ translation_step_read(Buffer_Model_Step step, Buffer_Model_Behavior *behavior_ou
}
}
#define TRANSLATION_DECL_OUTPUT(_j,_emit) u32 _j = 0; _j < (_emit).step_count; ++_j
#define TRANSLATION_DECL_EMIT_LOOP(_j,_emit) u32 _j = 0; _j < (_emit).step_count; ++_j
#define TRANSLATION_DECL_GET_STEP(_step,_behav,_j,_emit) \
Buffer_Model_Step _step = _emit.steps[_j]; Buffer_Model_Behavior _behav; \
translation_step_read(_step, &_behav)
#define TRANSLATION_OUTPUT(_j,_emit) _j = 0; _j < (_emit).step_count; ++_j
#define TRANSLATION_EMIT_LOOP(_j,_emit) _j = 0; _j < (_emit).step_count; ++_j
#define TRANSLATION_GET_STEP(_step,_behav,_j,_emit)\
(_step) = _emit.steps[_j]; translation_step_read((_step), &(_behav))

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;

View File

@ -31,10 +31,10 @@ internal
Sys_Font_Get_IDs_By_Index_Sig(system_font_get_ids_by_index){
b32 result = false;
u32 stop_index = first_index + index_count;
if (stop_index < win32_fonts.font_count){
if (stop_index <= win32_fonts.font_count){
result = true;
for (u32 i = first_index; i < stop_index; ++i){
id_out[i] = i;
id_out[i-first_index] = i;
}
}
return(result);
@ -46,8 +46,8 @@ Sys_Font_Get_Name_By_Index_Sig(system_font_get_name_by_index){
if (font_index < win32_fonts.font_count){
Render_Font *font = &win32_fonts.fonts[font_index];
char *name = font->name;
u32 name_len = font->name_len;
copy_partial_cs(str_out, str_out_cap, make_string(name, name_len));
length = font->name_len;
copy_partial_cs(str_out, str_out_cap, make_string(name, length));
}
return(length);
}