diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index c26d3af..d47e85b 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -226,11 +226,9 @@ API String16 GetLineStringWithoutNL(Buffer *buffer, Int line) { API Int PosToLine(Buffer *buffer, Int pos) { Add(&buffer->line_starts, buffer->len + 1); - // binary search - Int low = 0; - // -2 here because we use 2 indices and combine them into one line range so we // don't want to access last item since that would index past array. + Int low = 0; Int high = buffer->line_starts.len - 2; Int result = 0; @@ -745,7 +743,6 @@ inline bool MergeSortCompare(Edit *EntryA, Edit *EntryB) { template void MergeSort(int64_t Count, T *First, T *Temp) { - ProfileFunction(); // SortKey = range.min if (Count == 1) { // NOTE(casey): No work to do. @@ -823,7 +820,9 @@ API void ApplyEditsMultiCursor(Buffer *buffer, Array edits) { // We need to sort from lowest to highest based on range.min Scratch scratch(buffer->line_starts.allocator); Array edits_copy = TightCopy(scratch, edits); - if (edits.len > 1) MergeSort(edits.len, edits_copy.data, edits.data); + if (edits.len > 1) { + MergeSort(edits.len, edits_copy.data, edits.data); + } edits = edits_copy; #if BUFFER_DEBUG @@ -1368,14 +1367,28 @@ BufferID AllocBufferID(Buffer *buffer) { } Buffer *GetBuffer(BufferID id, Buffer *default_buffer = Buffers[0]) { - For(Buffers) { - if (it->id == id) return it; + Int left = 0; + Int right = Buffers.len - 1; + Buffer *result = default_buffer; + + while (left <= right) { + Int mid = left + (right - left) / 2; + Buffer *it = Buffers[mid]; + if (it->id == id) { + result = it; + break; + } else if (it->id.id < id.id) { + left = mid + 1; + } else { + right = mid - 1; + } } - return default_buffer; + + return result; } Buffer *GetBuffer(String name, Buffer *default_buffer = Buffers[0]) { - For(Buffers) { + For (Buffers) { if (it->name == name) return it; } return default_buffer; @@ -1506,18 +1519,6 @@ Buffer *BufferOpenFile(String path) { return buffer; } -bool BufferIsReferenced(Buffer *buffer) { - if (buffer->special) { - return true; - } - - if (FindView(buffer->id, NULL)) { - return true; - } - - return false; -} - void ReopenBuffer(Buffer *buffer) { Scratch scratch; @@ -1566,3 +1567,15 @@ String GetDirectory(Buffer *buffer) { String result = ChopLastSlash(buffer->name); return result; } + +void TryReopeningWhenModified(Buffer *it) { + if (it->file_mod_time) { + int64_t new_file_mod_time = GetFileModTime(it->name); + if (it->file_mod_time != new_file_mod_time) { + it->changed_on_disk = true; + if (it->dirty == false) { + ReopenBuffer(it); + } + } + } +} \ No newline at end of file diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index e6e87f0..c59b012 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -103,18 +103,14 @@ void ReportErrorf(const char *fmt, ...) { BREAK(); } - View *view = GetView(LogViewID); - if (view) { - Appendf(view, "%S\n", string); - } + Appendf(LogView, "%S\n", string); ShowUIMessagef("%S", string); } void ReportConsolef(const char *fmt, ...) { Scratch scratch; STRING_FORMAT(scratch, fmt, string); - View *view = GetView(LogViewID); - Appendf(view, "%S\n", string); + Appendf(LogView, "%S\n", string); } void ReportWarningf(const char *fmt, ...) { @@ -124,8 +120,7 @@ void ReportWarningf(const char *fmt, ...) { if (BreakOnError) { BREAK(); } - View *null_view = GetView(LogViewID); - Appendf(null_view, "%S\n", string); + Appendf(LogView, "%S\n", string); } void CMD_CenterView() { @@ -177,8 +172,7 @@ void ApplyFormattingTool(Buffer *buffer, String tool) { if (exec_result.exit_code == 0) { ReplaceWithoutMovingCarets(buffer, GetRange(buffer), string16); } else { - View *view = GetView(LogViewID); - Append(view, string16, true); + Append(LogView, string16, true); } } @@ -250,8 +244,7 @@ void CMD_ToggleFullscreen() { void CMD_OpenLogs() { ErrorCount = 0; - Buffer *buffer = GetBuffer(LogBufferID); - Open(buffer->name); + Open(LogBuffer->name); } RegisterCommand(CMD_OpenLogs, "", "Opens the text editor logs and clear error counter"); void CMD_Errors() { diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index 9245346..7482016 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -29,8 +29,8 @@ Array Windows; Array Views; Array Buffers; -BufferID LogBufferID; -ViewID LogViewID; +View *LogView; +Buffer *LogBuffer; BufferID NullBufferID; ViewID NullViewID; diff --git a/src/text_editor/plugin_remedybg.cpp b/src/text_editor/plugin_remedybg.cpp index 52574b4..4b13fa9 100644 --- a/src/text_editor/plugin_remedybg.cpp +++ b/src/text_editor/plugin_remedybg.cpp @@ -2111,7 +2111,7 @@ bool RDBG_InitConnection(mco_coro *co, bool create_session = true) { String session_name = Format(CoCurr->arena, "te%llu", GetTimeNanos()); String remedy_string = Format(CoCurr->arena, "%S --servername %S", RemedyBGPath, session_name); ReportConsolef("Remedybg: %S", remedy_string); - Exec(LogViewID, true, remedy_string, GetPrimaryDirectory()); + Exec(LogView->id, true, remedy_string, GetPrimaryDirectory()); MemoryZero(&RDBG_Ctx, sizeof(RDBG_Ctx)); RDBG_Ctx.cmd.data = command_buf; RDBG_Ctx.cmd.capacity = sizeof(command_buf); diff --git a/src/text_editor/plugin_search_window.cpp b/src/text_editor/plugin_search_window.cpp index 704de44..5639f1e 100644 --- a/src/text_editor/plugin_search_window.cpp +++ b/src/text_editor/plugin_search_window.cpp @@ -89,15 +89,17 @@ void LayoutSearchWindow(Rect2I *rect, int16_t wx, int16_t wy) { window->line_numbers_rect = CutLeft(&window->document_rect, window->font->char_spacing * 6); } +Int SearchBufferChangeID; void UpdateSearchWindow() { if (ActiveWindowID == SearchWindowID) { BSet active = GetBSet(ActiveWindowID); - if (active.buffer->begin_frame_change_id != active.buffer->change_id) { + if (SearchBufferChangeID != active.buffer->change_id) { BSet main = GetBSet(PrimaryWindowID); main.view->carets[0] = main.window->search_bar_anchor; String16 seek = GetString(active.buffer, GetRange(active.buffer)); Find(main.view, seek, true); CenterView(main.window->id); + SearchBufferChangeID = active.buffer->change_id; } } } diff --git a/src/text_editor/process.cpp b/src/text_editor/process.cpp index 1c2ff2c..f5ab160 100644 --- a/src/text_editor/process.cpp +++ b/src/text_editor/process.cpp @@ -8,7 +8,7 @@ void UpdateProcesses() { IterRemove(ActiveProcesses) { IterRemovePrepare(ActiveProcesses); Scratch scratch; - View *view = GetView({it.view_id}); + View *view = GetView(ViewID{it.view_id}); String poll = PollStdout(scratch, &it, false); if (poll.len) { diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index b8cd953..9792d9a 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -572,7 +572,7 @@ void GarbageCollect() { Dealloc(sys_allocator, it); remove_item = true; } else { - View *view = FindView(it->active_view, NULL); + View *view = GetView(it->active_view, NULL); if (!view) { JumpToLastValidView(it); } @@ -685,14 +685,6 @@ void Update(Event event) { UpdateScroll(it, !AreEqual(view->main_caret_on_begin_frame, view->carets[0]) && view->update_scroll); } - // We update it here despite the name to make it sure that all the possible changes are - // included albeit with delayed response. If we did this at the beginning of the frame - // and the DebugWindowUpdated we wouldnt get to know that in the OnCommand. - // @todo: this is slow, we don't want to loop through every buffer on every frame :( - For (Buffers) { - it->begin_frame_change_id = it->change_id; - } - { ProfileScope(UpdateWindows); For (Windows) { @@ -775,20 +767,10 @@ void Update(Event event) { } } - // Reopen modified buffers - // @todo: This is O(n) so could see slow downs with number of buffers, likely need OS help to make it more - // efficient - // @todo: maybe instead go through windows and only reopen active buffers - For(Buffers) { - if (it->file_mod_time) { - int64_t new_file_mod_time = GetFileModTime(it->name); - if (it->file_mod_time != new_file_mod_time) { - it->changed_on_disk = true; - if (it->dirty == false) { - ReopenBuffer(it); - } - } - } + // IS THIS ENOUGH? Previously reopened everything + For (Windows) { + BSet set = GetBSet(it); + TryReopeningWhenModified(set.buffer); } GarbageCollect(); @@ -984,10 +966,10 @@ int main(int argc, char **argv) Buffer *logs_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "logs", "")); logs_buffer->special = true; - LogBufferID = logs_buffer->id; View *logs_view = CreateView(logs_buffer->id); logs_view->special = true; - LogViewID = logs_view->id; + LogBuffer = logs_buffer; + LogView = logs_view; #if PLUGIN_RECORD_GC GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "gc")); diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 328fa07..85cf322 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -70,9 +70,7 @@ struct ResolvedOpen { struct Buffer { BufferID id; String name; - Int begin_frame_change_id; Int change_id; - Int user_change_id; Int file_mod_time; union { @@ -338,7 +336,6 @@ BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal); void CenterView(WindowID window); void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret = false); void JumpTempBuffer(BSet *set, String buffer_name = ""); -View *FindView(BufferID buffer_id, View *default_view = NULL); bool operator==(BufferID a, BufferID b) { return a.id == b.id; } bool operator==(ViewID a, ViewID b) { return a.id == b.id; } diff --git a/src/text_editor/ui.cpp b/src/text_editor/ui.cpp index 2575ad7..9ed87f1 100644 --- a/src/text_editor/ui.cpp +++ b/src/text_editor/ui.cpp @@ -365,7 +365,7 @@ BSet Open(Window *window, String path, ResolveOpenMeta meta, bool set_active = t Exec(set.view->id, false, o.path, GetPrimaryDirectory()); } else if (o.kind == OpenKind_BackgroundExec) { // this shouldn't change the focus/window/view - Exec(LogViewID, false, o.path, GetPrimaryDirectory()); + Exec(LogView->id, false, o.path, GetPrimaryDirectory()); } else if (o.kind == OpenKind_Command) { EvalCommand(o.path); } diff --git a/src/text_editor/view.cpp b/src/text_editor/view.cpp index ff4c16f..c25065e 100644 --- a/src/text_editor/view.cpp +++ b/src/text_editor/view.cpp @@ -20,18 +20,29 @@ void Dealloc(View *view) { Dealloc(view->carets.allocator, view); } -// TODO: default_view should probably be Views[0] but could break stuff -API View *FindView(ViewID view_id, View *default_view = NULL) { - For(Views) { - if (it->id == view_id) { - return it; +View *GetView(ViewID id, View *default_view = Views[0]) { + Int left = 0; + Int right = Views.len - 1; + View *result = default_view; + + while (left <= right) { + Int mid = left + (right - left) / 2; + View *it = Views[mid]; + if (it->id == id) { + result = it; + break; + } else if (it->id.id < id.id) { + left = mid + 1; + } else { + right = mid - 1; } } - return default_view; + + return result; } -API View *FindView(BufferID buffer_id, View *default_view) { - For(Views) { +API View *GetView(BufferID buffer_id, View *default_view = Views[0]) { + For (Views) { if (it->active_buffer == buffer_id) { return it; } @@ -39,8 +50,8 @@ API View *FindView(BufferID buffer_id, View *default_view) { return default_view; } -API View *FindView(String name, View *default_view = NULL) { - For(Views) { +API View *GetView(String name, View *default_view = Views[0]) { + For (Views) { Buffer *buffer = GetBuffer(it->active_buffer); if (buffer->name == name) { return it; @@ -49,10 +60,6 @@ API View *FindView(String name, View *default_view = NULL) { return default_view; } -API View *GetView(ViewID id) { - return FindView(id, Views[0]); -} - API View *OpenBufferView(String name) { Buffer *buffer = BufferOpenFile(name); View *view = CreateView(buffer->id); @@ -88,10 +95,22 @@ API bool ViewIsReferenced(View *view) { return ViewIsActive(view->id); } +bool BufferIsReferenced(Buffer *buffer) { + if (buffer->special) { + return true; + } + + if (GetView(buffer->id, NULL)) { + return true; + } + + return false; +} + void Close(ViewID id) { - View *view = GetView(id); + View *view = GetView(id, NULL); if (view) { - if (view->id.id == 0) { + if (view->special) { return; } view->close = true; diff --git a/src/text_editor/window.cpp b/src/text_editor/window.cpp index 61e314f..ecfdd09 100644 --- a/src/text_editor/window.cpp +++ b/src/text_editor/window.cpp @@ -45,19 +45,24 @@ Window *FindWindow(ViewID view_id, Window *default_window = NULL) { Window *FindWindow(String buffer_name, Window *default_window = NULL) { For(Windows) { - View *it_view = GetView(it->active_view); - Buffer *it_buffer = GetBuffer(it_view->active_buffer); - if (it_buffer->name == buffer_name) { - return it; + View *it_view = GetView(it->active_view, NULL); + if (it_view) { + Buffer *it_buffer = GetBuffer(it_view->active_buffer, NULL); + Assert(it_buffer); // Probably we are missing something when GCing / closing + if (it_buffer && it_buffer->name == buffer_name) { + return it; + } } } return default_window; } Window *FindWindow(BufferID buffer_id) { - For(Windows) { - View *view = GetView(it->active_view); - if (view->active_buffer == buffer_id) return it; + For (Windows) { + View *view = GetView(it->active_view, Views[0]); + if (view->active_buffer == buffer_id) { + return it; + } } return NULL; } @@ -92,7 +97,7 @@ Int GetExpandingBarSize(Window *window) { } View *WindowOpenBufferView(Window *new_parent_window, String name) { - View *view = FindView(name); + View *view = GetView(name, NULL); if (!view) { View *result = OpenBufferView(name); new_parent_window->active_view = result->id; @@ -192,7 +197,7 @@ Int ScreenSpaceToBufferPosErrorOutOfBounds(Window *window, View *view, Buffer *b GotoCrumb PopCrumb(Array *cr) { for (; cr->len;) { GotoCrumb c = Pop(cr); - View *view = FindView(c.view_id, NULL); + View *view = GetView(c.view_id, NULL); if (view) { return c; } @@ -203,12 +208,12 @@ GotoCrumb PopCrumb(Array *cr) { View *GetLastValidView(Window *window) { For (IterateInReverse(&window->goto_redo)) { if (it.view_id == window->active_view) continue; - View *view = FindView(it.view_id, NULL); + View *view = GetView(it.view_id, NULL); if (view) return view; } For (IterateInReverse(&window->goto_history)) { if (it.view_id == window->active_view) continue; - View *view = FindView(it.view_id, NULL); + View *view = GetView(it.view_id, NULL); if (view) return view; } return Views[0];