From f10212f4a0fb08cafaa1cd1ffa92ed938603f01f Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 10 Aug 2024 09:43:23 +0200 Subject: [PATCH] Move off from object arrays to id arrays --- src/text_editor/commands.cpp | 8 ++-- src/text_editor/lua_api.cpp | 15 +++--- src/text_editor/management.cpp | 81 ++++++++++++++++++--------------- src/text_editor/text_editor.cpp | 8 ++-- src/text_editor/text_editor.h | 6 +-- src/text_editor/title_bar.cpp | 9 ++-- src/text_editor/todo.txt | 3 +- src/text_editor/window.cpp | 65 +++++++++++++++----------- 8 files changed, 107 insertions(+), 88 deletions(-) diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index fad2a54..e1dd193 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -201,7 +201,7 @@ bool GlobalCommand(Event event) { Vec2I mouse = MouseVec2I(); For(order) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; bool mouse_in_total = CheckCollisionPointRec(mouse, window->total_rect); bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect); @@ -228,7 +228,7 @@ bool GlobalCommand(Event event) { Vec2I mouse = MouseVec2I(); For(order) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect); @@ -297,7 +297,7 @@ bool GlobalCommand(Event event) { if (MousePress()) { Vec2I mouse = MouseVec2I(); For(order) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect); if (mouse_in_document) { @@ -396,7 +396,7 @@ bool GlobalCommand(Event event) { // @todo: it generally works ok but it moves the scrollbar a bit on click // when mouse is not even moving For(order) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect); if (mouse_in_scrollbar) { diff --git a/src/text_editor/lua_api.cpp b/src/text_editor/lua_api.cpp index 996ebc2..f483468 100644 --- a/src/text_editor/lua_api.cpp +++ b/src/text_editor/lua_api.cpp @@ -152,7 +152,7 @@ int Lua_ListBuffers(lua_State *L) { Scratch scratch; Array strings = {scratch}; For(Buffers) { - String string = Format(scratch, "%.*s id=%d is_dir=%d", FmtString(it.name), (int)it.id.id, it.is_directory); + String string = Format(scratch, "%.*s id=%d is_dir=%d", FmtString(it.o->name), (int)it.id, it.o->is_directory); Add(&strings, string); } String result = Merge(scratch, strings, "\n"); @@ -173,9 +173,9 @@ int Lua_GetBufferList(lua_State *L) { int i = 1; For(Buffers) { - if (StartsWith(it.name, "+titlebar")) continue; + if (StartsWith(it.o->name, "+titlebar")) continue; lua_pushinteger(L, i++); - lua_pushlstring(L, it.name.data, it.name.len); + lua_pushlstring(L, it.o->name.data, it.o->name.len); lua_settable(L, -3); /* 3rd element from the stack top */ } /* We still have table left on top of the Lua stack. */ @@ -331,10 +331,11 @@ void UpdateLua() { ReloadStyle(); // @todo: maybe don't reload font if nothing changed ReloadFont(); - ForItem(window, Windows) { - if (!window.visible || window.absolute_position || window.is_title_bar) continue; - window.draw_scrollbar = StyleDrawScrollbar; - window.draw_line_numbers = StyleDrawLineNumbers; + For(Windows) { + Window *window = it.o; + if (!window->visible || window->absolute_position || window->is_title_bar) continue; + window->draw_scrollbar = StyleDrawScrollbar; + window->draw_line_numbers = StyleDrawLineNumbers; } } else { const char *error_message = lua_tostring(LuaState, -1); diff --git a/src/text_editor/management.cpp b/src/text_editor/management.cpp index 3933fa5..25c28a0 100644 --- a/src/text_editor/management.cpp +++ b/src/text_editor/management.cpp @@ -2,9 +2,9 @@ WindowID WindowIDs = {0}; BufferID BufferIDs = {0}; ViewID ViewIDs = {0}; -Array Buffers = {}; -Array Views = {}; -Array Windows = {}; +Array Buffers = {}; +Array Views = {}; +Array Windows = {}; WindowID NullWindowID; BufferID NullBufferID; @@ -25,6 +25,13 @@ WindowID ScrollbarSelected = {-1}; WindowID DocumentSelected = {-1}; Range DocumentRangeAnchor; +inline bool operator==(WindowID a, WindowID b) { return a.id == b.id; } +inline bool operator==(BufferID a, BufferID b) { return a.id == b.id; } +inline bool operator==(ViewID a, ViewID b) { return a.id == b.id; } +inline bool operator!=(WindowID a, WindowID b) { return a.id != b.id; } +inline bool operator!=(BufferID a, BufferID b) { return a.id != b.id; } +inline bool operator!=(ViewID a, ViewID b) { return a.id != b.id; } + inline bool IsDocumentSelectionValid() { if (DocumentSelected.id == -1) return false; return true; @@ -40,37 +47,30 @@ inline WindowID AllocWindowID(Window *window) { return {WindowIDs.id++, window}; inline BufferID AllocBufferID(Buffer *buffer) { return {BufferIDs.id++, buffer}; } inline Window *GetWindow(WindowID id) { - For(Windows) if (it.id.id == id.id) return ⁢ - return &Windows[0]; + For(Windows) if (it == id) return it.o; + return Windows[0].o; } inline Buffer *GetBuffer(BufferID id) { - For(Buffers) if (it.id.id == id.id) return ⁢ - return &Buffers[0]; + For(Buffers) if (it == id) return it.o; + return Buffers[0].o; } inline Buffer *GetBuffer(String name) { - For(Buffers) if (it.name == name) return ⁢ - return &Buffers[0]; + For(Buffers) if (it.o->name == name) return it.o; + return Buffers[0].o; } inline Buffer *BufferNameExists(String name) { - For(Buffers) if (it.name == name) return ⁢ + For(Buffers) if (it.o->name == name) return it.o; return NULL; } inline View *GetView(ViewID id) { - For(Views) if (it.id.id == id.id) return ⁢ - return &Views[0]; + For(Views) if (it == id) return it.o; + return Views[0].o; } -inline bool operator==(WindowID a, WindowID b) { return a.id == b.id; } -inline bool operator==(BufferID a, BufferID b) { return a.id == b.id; } -inline bool operator==(ViewID a, ViewID b) { return a.id == b.id; } -inline bool operator!=(WindowID a, WindowID b) { return a.id != b.id; } -inline bool operator!=(BufferID a, BufferID b) { return a.id != b.id; } -inline bool operator!=(ViewID a, ViewID b) { return a.id != b.id; } - inline bool IsNull(Buffer *buffer) { return buffer->id.id == NullBufferID.id; } inline bool IsActive(Window *window) { return window->id.id == ActiveWindow.id; } inline bool IsActive(Window *window, View *view) { return window->active_view.id == view->id.id; } @@ -89,51 +89,58 @@ void InitBuffer(Allocator allocator, Buffer *buffer, String name, Int size = 409 } Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096) { - Buffer *result = Alloc(&Buffers); + Buffer *result = AllocType(allocator, Buffer); InitBuffer(allocator, result, name, size); + Add(&Buffers, result->id); return result; } Buffer *CreateTempBuffer(Allocator allocator, Int size = 4096) { - Buffer *result = AllocType(allocator, Buffer); + Buffer *result = AllocType(allocator, Buffer); + result->no_history = true; InitBuffer(allocator, result, "*temp*", size); return result; } -Window *CreateWindow() { - Window *w = Alloc(&Windows); +Window *CreateWindow(bool insert_into_windows = true) { + Window *w = AllocType(Perm, Window); w->visible = true; w->draw_scrollbar = StyleDrawScrollbar; w->draw_line_numbers = StyleDrawLineNumbers; w->id = AllocWindowID(w); + if (insert_into_windows) Add(&Windows, w->id); return w; } View *CreateView(BufferID active_buffer) { - View *w = Alloc(&Views); - w->id = AllocViewID(w); - w->active_buffer = active_buffer; - Add(&w->carets, {0, 0}); - return w; + View *view = AllocType(Perm, View); + view->id = AllocViewID(view); + view->active_buffer = active_buffer; + Add(&view->carets, {0, 0}); + Add(&Views, view->id); + return view; } +// @todo: remove function void SetActiveWindow(WindowID window) { ActiveWindow = window; } View *FindView(BufferID buffer_id) { For(Views) { - if (it.active_buffer == buffer_id) { - return ⁢ + View *view = it.o; + if (view->active_buffer == buffer_id) { + return view; } } return NULL; } Window *GetWindowWithView(ViewID view_id) { - ForItem(window, Windows) { - if (window.active_view.id == view_id.id) { - return &window; + For(Windows) { + Window *window = it.o; + if (window->active_view.id == view_id.id) { + return window; } } return NULL; @@ -141,10 +148,10 @@ Window *GetWindowWithView(ViewID view_id) { Window *GetWindowWithView(String buffer_name) { For(Windows) { - View *it_view = GetView(it.active_view); + View *it_view = GetView(it.o->active_view); Buffer *it_buffer = GetBuffer(it_view->active_buffer); if (it_buffer->name == buffer_name) { - return ⁢ + return it.o; } } return NULL; @@ -152,9 +159,9 @@ Window *GetWindowWithView(String buffer_name) { View *FindViewWithBufferName(String name) { For(Views) { - Buffer *buffer = GetBuffer(it.active_buffer); + Buffer *buffer = GetBuffer(it.o->active_buffer); if (buffer->name == name) { - return ⁢ + return it.o; } } return NULL; diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 2d3017d..d31cb2c 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -164,7 +164,7 @@ void HandleEvent(Event event) { WindowCommand(event, window, view); MergeCarets(view); } - For(Windows) if (it.is_title_bar) ReplaceTitleBarData(&it); + For(Windows) if (it.o->is_title_bar) ReplaceTitleBarData(it.o); } void Update(Event event) { @@ -174,7 +174,7 @@ void Update(Event event) { Scratch scratch; Array order = GetWindowZOrder(scratch); For(order) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; View *view = GetActiveView(window); view->main_caret_on_begin_frame = view->carets[0]; @@ -188,7 +188,7 @@ void Update(Event event) { UpdateDebugBuffer(); For(IterateInReverse(&order)) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; View *view = GetView(window->active_view); @@ -352,7 +352,7 @@ int main(int argc, char **argv) BeginFrameRender(); Array order = GetWindowZOrder(scratch); For(IterateInReverse(&order)) { - Window *window = &Windows[it]; + Window *window = Windows[it].o; if (!window->visible) continue; DrawWindow(window, *GetLast(frame_events)); } diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 886bdff..871ad6b 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -1,8 +1,8 @@ // clang-format off struct Buffer; struct Window; struct View; -struct BufferID { Int id; Buffer *d; }; -struct ViewID { Int id; View *d; }; -struct WindowID { Int id; Window *d; }; // @warning refs are for debug !!! +struct BufferID { Int id; Buffer *o; }; +struct ViewID { Int id; View *o; }; +struct WindowID { Int id; Window *o; }; // @todo: change name of object to something scary union Range { struct { Int min; Int max; }; Int e[2]; }; struct Caret { union { Range range; Int pos[2]; }; Int ifront;}; diff --git a/src/text_editor/title_bar.cpp b/src/text_editor/title_bar.cpp index b4edfa1..7790a69 100644 --- a/src/text_editor/title_bar.cpp +++ b/src/text_editor/title_bar.cpp @@ -2,8 +2,9 @@ String DebugViewList(Allocator allocator) { Scratch scratch((Arena *)allocator.object); Array strings = {scratch}; For(Views) { - Buffer *buffer = GetBuffer(it.active_buffer); - String string = Format(scratch, "view = %lld buffer = %lld name = %.*s", (long long)it.id.id, (long long)buffer->id.id, FmtString(buffer->name)); + View *view = it.o; + Buffer *buffer = GetBuffer(view->active_buffer); + String string = Format(scratch, "view = %lld buffer = %lld name = %.*s", (long long)view->id.id, (long long)buffer->id.id, FmtString(buffer->name)); Add(&strings, string); } String result = Merge(allocator, strings, "\n"); @@ -14,9 +15,9 @@ String DebugWindowList(Allocator allocator) { Scratch scratch((Arena *)allocator.object); Array strings = {scratch}; For(Windows) { - View *view = GetActiveView(&it); + View *view = GetActiveView(it.o); Buffer *buffer = GetBuffer(view->active_buffer); - String string = Format(scratch, "window = %lld active_view = %lld buffer_name = %.*s", (long long)it.id.id, (long long)it.active_view.id, FmtString(buffer->name)); + String string = Format(scratch, "window = %lld active_view = %lld buffer_name = %.*s", (long long)it.id, (long long)view->id.id, FmtString(buffer->name)); Add(&strings, string); } String result = Merge(allocator, strings, "\n"); diff --git a/src/text_editor/todo.txt b/src/text_editor/todo.txt index 704f0d4..54489dc 100644 --- a/src/text_editor/todo.txt +++ b/src/text_editor/todo.txt @@ -1,4 +1,4 @@ -- Remove pointers and use ViewIDs (enable array debug while doing this) +- garbage collect the buffers, views - store them in free list on destroy - Remove console and command window, provide alternatives but unify the interface? - We can create 2 buffers with same name - window splitting leaves a whitegap at the end @@ -7,7 +7,6 @@ - apply clang format - apply clang format on save - OnWindowCommand allow config user to overwrite the WindowCommand keybinding, introduce his own -- How to remove memory issues? Maybe just store ids and pointers in arrays, rest should be allocated off of arena. Then maybe garbage collected and reclaimed. - ctrl + f - should find Search and select content or add Search - some split selection commands diff --git a/src/text_editor/window.cpp b/src/text_editor/window.cpp index c0a796c..067a493 100644 --- a/src/text_editor/window.cpp +++ b/src/text_editor/window.cpp @@ -5,16 +5,17 @@ struct VisualColumn { Array GetVisualColumns(Allocator allocator) { Array columns = {allocator}; - ForItem(window, Windows) { - if (!window.visible || window.absolute_position || window.is_title_bar) continue; + For(Windows) { + Window *window = it.o; + if (!window->visible || window->absolute_position || window->is_title_bar) continue; - if (window.is_column) { - Add(&columns, {&window, {allocator}}); + if (window->is_column) { + Add(&columns, {window, {allocator}}); VisualColumn *col = GetLast(columns); - Add(&col->rows, &window); + Add(&col->rows, window); } else if (columns.len) { VisualColumn *col = GetLast(columns); - Add(&col->rows, &window); + Add(&col->rows, window); } } return columns; @@ -22,9 +23,11 @@ Array GetVisualColumns(Allocator allocator) { Window *GetLayoutWindow(int n) { int i = 0; - ForItem(window, Windows) { - if (!window.visible || window.absolute_position || window.is_title_bar) continue; - if (n == i) return &window; + For(Windows) { + Window *window = it.o; + if (!window->is_column || !window->visible || window->absolute_position || window->is_title_bar) continue; + + if (n == i) return window; i += 1; } return NULL; @@ -32,9 +35,9 @@ Window *GetLayoutWindow(int n) { Array GetWindowZOrder(Allocator allocator) { Array order = {allocator}; - For(Windows) if (it.z == 2) Add(&order, GetIndex(Windows, it)); - For(Windows) if (it.z == 1) Add(&order, GetIndex(Windows, it)); - For(Windows) if (it.z == 0) Add(&order, GetIndex(Windows, it)); + For(Windows) if (it.o->z == 2) Add(&order, GetIndex(Windows, it)); + For(Windows) if (it.o->z == 1) Add(&order, GetIndex(Windows, it)); + For(Windows) if (it.o->z == 0) Add(&order, GetIndex(Windows, it)); return order; } @@ -77,21 +80,27 @@ void AddColumnWindow() { CreateTitlebar(window->id); } -void AddRowWindow() { - Window *window = CreateWindow(); - WindowID window_id = window->id; +Int GetWindowIndex(WindowID window_id) { + Int i = 0; + For(Windows) { + if (window_id == it) return i; + i += 1; + } + return 0; +} - View *view = OpenBufferView("+scratch"); - window->active_view = view->id; +void AddRowWindow() { + Window *active_window = GetActiveWindow(); + Window *window = CreateWindow(); + View *view = OpenBufferView("+scratch"); + window->active_view = view->id; CreateTitlebar(window->id); - Window *active_window = GetActiveWindow(); - int64_t active_window_index = GetIndex(Windows, *active_window); + Int i0 = GetWindowIndex(window->id); + RemoveByIndex(&Windows, i0); - window = GetWindow(window_id); - Window window_copy = *window; - Remove(&Windows, *window); - Insert(&Windows, window_copy, active_window_index + 1); + Int active_window_index = GetWindowIndex(active_window->id); + Insert(&Windows, window->id, active_window_index + 1); } void SetVisibility(WindowID window_id, bool v) { @@ -184,17 +193,19 @@ void LayoutWindows() { float delta_column = 1.0f / (float)columns.len; ForItem(col, columns) { - Rect2I rect = CutLeft(&screen_rect, (Int)(delta_column * sizex)); + Int add = 0; + if (IsLast(columns, col)) add += 2; - float sizey = (float)GetSize(rect).y; - float delta_row = 1.0f / (float)col.rows.len; + Rect2I rect = CutLeft(&screen_rect, (Int)(delta_column * sizex + add)); + float sizey = (float)GetSize(rect).y; + float delta_row = 1.0f / (float)col.rows.len; ForItem(row, col.rows) { row->total_rect = CutTop(&rect, (Int)(delta_row * sizey)); } } For(Windows) { - Window *window = ⁢ + Window *window = it.o; if (!window->visible || window->absolute_position || window->is_title_bar) continue; Window *title_bar_window = GetWindow(window->title_bar_window);