fixed up file track issue
							parent
							
								
									1f064acbb7
								
							
						
					
					
						commit
						30a2a95b69
					
				
							
								
								
									
										21
									
								
								4ed.cpp
								
								
								
								
							
							
						
						
									
										21
									
								
								4ed.cpp
								
								
								
								
							|  | @ -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); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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); | ||||
|          | ||||
|  |  | |||
							
								
								
									
										13
									
								
								TODO.txt
								
								
								
								
							
							
						
						
									
										13
									
								
								TODO.txt
								
								
								
								
							|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
|                 } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster