fixed up file track issue

master
Allen Webster 2016-09-13 15:56:14 -04:00
parent 1f064acbb7
commit 30a2a95b69
6 changed files with 120 additions and 97 deletions

21
4ed.cpp
View File

@ -353,13 +353,17 @@ COMMAND_DECL(reopen){
General_Memory *general = &models->mem.general;
File_Edit_Positions edit_poss[16];
int32_t line_number[16];
int32_t column_number[16];
View *vptrs[16];
i32 vptr_count = 0;
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
vptrs[vptr_count] = iter.view;
edit_poss[vptr_count] = *iter.view->edit_pos;
edit_poss[vptr_count] = iter.view->edit_pos[0];
line_number[vptr_count] = iter.view->edit_pos[0].cursor.line;
column_number[vptr_count] = iter.view->edit_pos[0].cursor.character;
iter.view->edit_pos = 0;
++vptr_count;
}
@ -367,13 +371,18 @@ COMMAND_DECL(reopen){
file_close(system, general, file);
init_normal_file(system, models, file, buffer, size);
for (i32 i = 0;
i < vptr_count;
++i){
for (i32 i = 0; i < vptr_count; ++i){
view_set_file(vptrs[i], file, models);
int32_t line = line_number[i];
int32_t column = column_number[i];
*vptrs[i]->edit_pos = edit_poss[i];
view_set_cursor(vptrs[i], edit_poss[i].cursor,
true, view->file_data.unwrapped_lines);
Full_Cursor cursor =
view_compute_cursor_from_line_pos(vptrs[i], line, column);
view_set_cursor(vptrs[i], cursor, true,
view->file_data.unwrapped_lines);
}
}
}

View File

@ -41,11 +41,7 @@ struct File_Edit_Positions{
i32 last_set_type;
b32 in_view;
};
inline File_Edit_Positions
file_edit_positions_zero(){
File_Edit_Positions data = {0};
return(data);
}
static File_Edit_Positions null_edit_pos = {0};
enum Edit_Type{
ED_NORMAL,

View File

@ -505,14 +505,14 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){
Full_Cursor result;
if (view->file_data.unwrapped_lines) result = view_compute_cursor_from_unwrapped_xy(view, seek_x, seek_y);
else result = view_compute_cursor_from_wrapped_xy(view, seek_x, seek_y);
return result;
return(result);
}
inline i32
view_wrapped_line_span(f32 line_width, f32 max_width){
i32 line_count = CEIL32(line_width / max_width);
if (line_count == 0) line_count = 1;
return line_count;
return(line_count);
}
internal i32
@ -535,7 +535,7 @@ view_compute_lowest_line(View *view){
lowest_line += line_span - 1;
}
}
return lowest_line;
return(lowest_line);
}
inline i32
@ -646,10 +646,8 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll,
}
internal void
view_set_cursor(View *view,
Full_Cursor cursor,
b32 set_preferred_x,
b32 unwrapped_lines){
view_set_cursor(View *view, Full_Cursor cursor,
b32 set_preferred_x, b32 unwrapped_lines){
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
edit_pos_set_cursor_(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);

View File

@ -1,10 +1,11 @@
; Started this list on: (18.01.2016)(dd.mm.yyyy)
; This list is an informal todo list, it may very well miss items
; checked or unchecked, that I inted to do some day. It is included
; in the distribution so that you may take a look and see if your
; requested feature is there, and if not, so that you may remind me.
; Cheers everyone!
;
; BUGS
; [X] '\t' thing
; [X] smoothness in smoothscrolling isn't very smooth
@ -74,6 +75,7 @@
; [X] paths with parens in them
; [X] killing compilation panel changes active panel
; [X] make panel resizing not whacky with child panels
; [X] visual studio file saves aren't picked up by the file track system
;
; [] indication on failure to save
; [] history is broken, revist the entire system
@ -83,12 +85,6 @@
; [] view fails to follow cursor when the view is shrunk
; [] view fails to follow cursor after deleting long line
;
;
; BEFORE I SHIP
;
; [] occasionally missing the (!) mark on files on windows
;
; TODOS
; [X] success message when compiler works
@ -144,7 +140,7 @@
; [] switch to line classification system
; [] more built in options for auto indenting
;
;
; [] binary buffers
; [] commands for resizing panels
; [] user file bar string
@ -273,6 +269,7 @@
; [] a triangle rendered for a few frames? color of the dirty markers (not reproduced by me yet)
; [] minimize and reopen problem (not reproduced by me yet)
;
;
; FANCY-PANTS IDEAS
; [] pass messages to 'jobs' to try to avoid cancelling them

View File

@ -867,4 +867,3 @@ int main(int argc, char **argv){
#endif
// BOTTOM

View File

@ -116,6 +116,17 @@ internal_get_file_index(BY_HANDLE_FILE_INFORMATION info){
return(hash);
}
#define FLAGS ( \
FILE_NOTIFY_CHANGE_FILE_NAME | \
FILE_NOTIFY_CHANGE_DIR_NAME | \
FILE_NOTIFY_CHANGE_ATTRIBUTES | \
FILE_NOTIFY_CHANGE_SIZE | \
FILE_NOTIFY_CHANGE_LAST_WRITE | \
FILE_NOTIFY_CHANGE_LAST_ACCESS| \
FILE_NOTIFY_CHANGE_SECURITY | \
FILE_NOTIFY_CHANGE_CREATION | \
0)
FILE_TRACK_LINK File_Track_Result
add_listener(File_Track_System *system, char *filename){
File_Track_Result result = FileTrack_Good;
@ -157,8 +168,8 @@ add_listener(File_Track_System *system, char *filename){
if (ReadDirectoryChangesW(dir,
node->listener.result,
sizeof(node->listener.result),
0,
FILE_NOTIFY_CHANGE_LAST_WRITE,
1,
FLAGS,
0,
&node->listener.overlapped,
0)){
@ -250,6 +261,7 @@ remove_listener(File_Track_System *system, char *filename){
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);
}
@ -316,6 +328,10 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *
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;
EnterCriticalSection(&vars->table_lock);
{
@ -323,78 +339,83 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *
DWORD length = 0;
ULONG_PTR key = 0;
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.
Win32_Directory_Listener listener = *listener_ptr;
ZeroStruct(listener_ptr->overlapped);
ReadDirectoryChangesW(listener_ptr->dir,
listener_ptr->result,
sizeof(listener_ptr->result),
0,
FILE_NOTIFY_CHANGE_LAST_WRITE,
0,
&listener_ptr->overlapped,
0);
char *listener_buffer = listener.result;
DWORD offset = 0;
FILE_NOTIFY_INFORMATION *info = 0;
for (;;){
info = (FILE_NOTIFY_INFORMATION*)(listener_buffer + offset);
int32_t 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;
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;
// 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);
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 (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;
break;
}
else{
break;
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;
}
}
}
@ -424,6 +445,9 @@ shut_down_track_system(File_Track_System *system){
if (!entry_is_available(entry)){
Win32_File_Track_Entry *win32_entry = (Win32_File_Track_Entry*)entry;
if (!CancelIo(win32_entry->dir)){
win32_result = 1;
}
if (!CloseHandle(win32_entry->dir)){
win32_result = 1;
}