Switch to using arrays for Windows, Views, Buffers list, try to make DeleteWindow work

This commit is contained in:
Krzosa Karol
2025-12-05 08:58:46 +01:00
parent 05f0197d50
commit e6e1ae0223
12 changed files with 106 additions and 115 deletions

View File

@@ -24,12 +24,11 @@ Splits:
- Buffer16 Buffer8? - Buffer16 Buffer8?
- Why constraint that name of buffer needs to be unique? For Open() and default behavior but is this required? - Why constraint that name of buffer needs to be unique? For Open() and default behavior but is this required?
- Try to add Tracking Allocator and rewrite the app, free all memory at the end of the app and check all is well - Try to add Tracking Allocator and rewrite the app, free all memory at the end of the app and check all is well
- SpawnProcess wrong memory allocation there - move titlebar, search to splits?
- Trying to fix the testing, Command_Open doesn't work on first frame because window is not metricly OK?
- window->document_rect is null
Linux
- Add backtrace

View File

@@ -759,7 +759,6 @@ API Process SpawnProcess(String command_line, String working_dir, String write_s
String16 cmd = ToString16(scratch, command_line); String16 cmd = ToString16(scratch, command_line);
char *env = NULL; char *env = NULL;
// TODO: FIX ARENA ALLOCATION USING PushSize, Prealloc maybe? Maybe we want a block arena
if (enviroment.len) { if (enviroment.len) {
Int size = GetSize(enviroment) + enviroment.len + 1; Int size = GetSize(enviroment) + enviroment.len + 1;
env = (char *)PushSize(scratch, size); env = (char *)PushSize(scratch, size);

View File

@@ -917,16 +917,16 @@ API void AddEdit(Array<Edit> *e, Range range, String16 string) {
void SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) { void SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) {
if (buffer->no_history) return; if (buffer->no_history) return;
HistoryEntry entry = {}; HistoryEntry entry = {};
entry.carets = TightCopy(GetSystemAllocator(), carets); entry.carets = TightCopy(GetSystemAllocator(), carets);
Add(stack, entry); Add(stack, entry);
} }
void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array<HistoryEntry> *stack, Array<Edit> &edits) { void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array<HistoryEntry> *stack, Array<Edit> &edits) {
ProfileFunction(); ProfileFunction();
if (buffer->no_history) return; if (buffer->no_history) return;
HistoryEntry *entry = GetLast(*stack); HistoryEntry *entry = GetLast(*stack);
Allocator sys_allocator = GetSystemAllocator(); Allocator sys_allocator = GetSystemAllocator();
entry->edits = TightCopy(sys_allocator, edits); entry->edits = TightCopy(sys_allocator, edits);
// Make reverse edits // Make reverse edits
For(entry->edits) { For(entry->edits) {
@@ -1170,8 +1170,6 @@ API void InitBuffer(Allocator allocator, Buffer *buffer, BufferID id = {}, Strin
} }
API void DeinitBuffer(Buffer *buffer) { API void DeinitBuffer(Buffer *buffer) {
Assert(buffer->next == NULL);
Assert(buffer->prev == NULL);
Allocator allocator = buffer->line_starts.allocator; Allocator allocator = buffer->line_starts.allocator;
Dealloc(allocator, buffer->data); Dealloc(allocator, buffer->data);
Dealloc(&buffer->line_starts); Dealloc(&buffer->line_starts);

View File

@@ -16,8 +16,6 @@ struct HistoryEntry {
struct Buffer { struct Buffer {
BufferID id; BufferID id;
Buffer *next;
Buffer *prev;
String name; String name;
Int change_id; Int change_id;
Int user_change_id; Int user_change_id;

View File

@@ -115,7 +115,7 @@ View *GetViewForFixingWhenBufferCommand(Buffer *buffer, bool *is_active = NULL)
return active_view; return active_view;
} }
for (View *it = FirstView; it; it = it->next) { For(Views) {
if (it->active_buffer != buffer->id) { if (it->active_buffer != buffer->id) {
continue; continue;
} }
@@ -154,7 +154,7 @@ void Command_Append(View *view, String16 string, bool scroll_to_end_if_cursor_on
}; };
Array<ViewInfo> view_info = {scratch}; Array<ViewInfo> view_info = {scratch};
for (View *it_view = FirstView; it_view; it_view = it_view->next) { ForItem(it_view, Views) {
if (it_view->active_buffer != buffer->id) { if (it_view->active_buffer != buffer->id) {
continue; continue;
} }
@@ -695,7 +695,7 @@ int Lua_Save(lua_State *L) {
} }
void Command_SaveAll() { void Command_SaveAll() {
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
if (it->file_mod_time) { if (it->file_mod_time) {
SaveBuffer(it); SaveBuffer(it);
} }
@@ -1230,7 +1230,7 @@ void Command_ListBuffers() {
BSet main = GetActiveMainSet(); BSet main = GetActiveMainSet();
ActiveWindow = main.window->id; ActiveWindow = main.window->id;
JumpGarbageBuffer(&main); JumpGarbageBuffer(&main);
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
RawAppendf(main.buffer, "%-80S || %S\n", SkipToLastSlash(it->name), it->name); RawAppendf(main.buffer, "%-80S || %S\n", SkipToLastSlash(it->name), it->name);
} }
main.view->fuzzy_search = true; main.view->fuzzy_search = true;
@@ -1247,7 +1247,7 @@ void Command_ListViews() {
BSet main = GetActiveMainSet(); BSet main = GetActiveMainSet();
ActiveWindow = main.window->id; ActiveWindow = main.window->id;
JumpGarbageBuffer(&main); JumpGarbageBuffer(&main);
for (View *it = FirstView; it; it = it->next) { For(Views) {
Buffer *buffer = GetBuffer(it->active_buffer); Buffer *buffer = GetBuffer(it->active_buffer);
Command_Appendf(main.view, "%d %S\n", (int)it->id.id, buffer->name); Command_Appendf(main.view, "%d %S\n", (int)it->id.id, buffer->name);
} }
@@ -1317,10 +1317,10 @@ int Lua_ListCommands(lua_State *L) {
} }
int Lua_GetBufferList(lua_State *L) { int Lua_GetBufferList(lua_State *L) {
lua_createtable(L, 0, (int)BufferCount); lua_createtable(L, 0, (int)Buffers.len);
int i = 1; int i = 1;
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
lua_pushinteger(L, i++); lua_pushinteger(L, i++);
lua_pushlstring(L, it->name.data, it->name.len); lua_pushlstring(L, it->name.data, it->name.len);
lua_settable(L, -3); /* 3rd element from the stack top */ lua_settable(L, -3); /* 3rd element from the stack top */
@@ -1330,7 +1330,7 @@ int Lua_GetBufferList(lua_State *L) {
} }
Window *GetOverlappingWindow(Vec2I p, Window *default_window = NULL) { Window *GetOverlappingWindow(Vec2I p, Window *default_window = NULL) {
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
if (AreOverlapping(p, it->total_rect)) { if (AreOverlapping(p, it->total_rect)) {
return it; return it;
} }

View File

@@ -283,6 +283,11 @@ void OnCommand(Event event) {
} }
} }
if (CtrlPress(SDLK_W)) {
BSet main = GetActiveMainSet();
main.window->kill = true;
}
if (CtrlAltPress(SDLK_P)) { if (CtrlAltPress(SDLK_P)) {
Command_ListBuffers(); Command_ListBuffers();

View File

@@ -297,7 +297,7 @@ void ReloadLuaConfigs(bool reload = false) {
ReloadStyle(); ReloadStyle();
ReloadFont(); ReloadFont();
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
if (it->is_title_bar || it->is_search_bar) { if (it->is_title_bar || it->is_search_bar) {
continue; continue;
} }

View File

@@ -1,17 +1,9 @@
WindowID WindowIDs; WindowID WindowIDs;
ViewID ViewIDs; ViewID ViewIDs;
Window *FirstWindow; Array<Window *> Windows;
Window *LastWindow; Array<View *> Views;
Int WindowCount; Array<Buffer *> Buffers;
View *FirstView;
View *LastView;
Int ViewCount;
Buffer *FirstBuffer;
Buffer *LastBuffer;
Int BufferCount;
// console // console
BufferID NullBufferID; BufferID NullBufferID;
@@ -100,46 +92,46 @@ inline ViewID AllocViewID(View *view) { return {ViewIDs.id++, view}; }
inline WindowID AllocWindowID(Window *window) { return {WindowIDs.id++, window}; } inline WindowID AllocWindowID(Window *window) { return {WindowIDs.id++, window}; }
inline BufferID AllocBufferID(Buffer *buffer) { return {BufferIDs++, buffer}; } inline BufferID AllocBufferID(Buffer *buffer) { return {BufferIDs++, buffer}; }
inline Window *GetWindow(WindowID id) { inline Window *GetWindow(WindowID id, Window *default_window = Windows[0]) {
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
if (it->id == id) return it; if (it->id == id) return it;
} }
return FirstWindow; return default_window;
} }
inline Buffer *GetBuffer(BufferID id) { inline Buffer *GetBuffer(BufferID id) {
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
if (it->id == id) return it; if (it->id == id) return it;
} }
return FirstBuffer; return Buffers[0];
} }
inline Buffer *FindBuffer(BufferID id) { inline Buffer *FindBuffer(BufferID id) {
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
if (it->id == id) return it; if (it->id == id) return it;
} }
return NULL; return NULL;
} }
inline Buffer *GetBuffer(String name) { inline Buffer *GetBuffer(String name) {
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
if (it->name == name) return it; if (it->name == name) return it;
} }
return FirstBuffer; return Buffers[0];
} }
inline Buffer *FindBuffer(String name) { inline Buffer *FindBuffer(String name) {
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
if (it->name == name) return it; if (it->name == name) return it;
} }
return NULL; return NULL;
} }
inline View *GetView(ViewID id) { inline View *GetView(ViewID id) {
for (View *it = FirstView; it; it = it->next) { For(Views) {
if (it->id == id) return it; if (it->id == id) return it;
} }
return FirstView; return Views[0];
} }
inline bool IsNull(Buffer *buffer) { return buffer->id.id == NullBufferID.id; } inline bool IsNull(Buffer *buffer) { return buffer->id.id == NullBufferID.id; }
@@ -147,55 +139,61 @@ inline Window *GetActiveWind() { return GetWindow(ActiveWindow); }
Buffer *CreateBuffer(Allocator allocator, String name, Int size) { Buffer *CreateBuffer(Allocator allocator, String name, Int size) {
Buffer *result = AllocBuffer(allocator, name, size); Buffer *result = AllocBuffer(allocator, name, size);
DLL_QUEUE_ADD(FirstBuffer, LastBuffer, result); Add(&Buffers, result);
BufferCount += 1;
return result; return result;
} }
Window *CreateWind(bool create_command_buffer = true) { Window *CreateWind(bool create_command_buffer = true) {
Window *w = AllocType(SysAllocator, Window); Allocator allocator = GetSystemAllocator();
Window *w = AllocType(allocator, Window);
w->font = &PrimaryFont; w->font = &PrimaryFont;
w->visible = true; w->visible = true;
w->draw_scrollbar = StyleDrawScrollbar; w->draw_scrollbar = StyleDrawScrollbar;
w->draw_line_numbers = StyleDrawLineNumbers; w->draw_line_numbers = StyleDrawLineNumbers;
w->id = AllocWindowID(w); w->id = AllocWindowID(w);
DLL_QUEUE_ADD(FirstWindow, LastWindow, w); Add(&Windows, w);
WindowCount += 1;
return w; return w;
} }
// void DestroyWindow(Window *window) { void DestroyWindow(Window *window) {
// WindowSplit *split = window->split_ref; Allocator allocator = GetSystemAllocator();
// if (split->parent == NULL) { window->kill = true;
// Assert(split->kind == WindowSplitKind_Window); WindowSplit *split = window->split_ref;
// return; if (split && split->parent) {
// } Assert(split->kind == WindowSplitKind_Window);
//
// WindowSplit *p = split->parent; WindowSplit *p = split->parent;
// WindowSplit *valid_node = p->left == split ? p->right : p->left; WindowSplit *pp = p->parent;
// if (p->parent == NULL) { WindowSplit *other = p->left == split ? p->right : p->left;
// // @todo:
// } else { if (pp) {
// valid_node->parent = p->parent; if (pp->left == p) {
// *p = *valid_node; pp->left = other;
// } } else {
// pp->right = other;
// // @leak window }
// DLL_QUEUE_REMOVE(FirstWindow, LastWindow, window); other->parent = pp;
// WindowCount -= 1; }
//
// if (window->search_bar_window.id) { Dealloc(allocator, p);
// Window *s = GetWindow(window->search_bar_window); Dealloc(allocator, split);
// DLL_QUEUE_REMOVE(FirstWindow, LastWindow, s); }
// WindowCount -= 1;
// }
// if (!window->is_search_bar && window->search_bar_window.id) {
// if (window->title_bar_window.id) { Window *s = GetWindow(window->search_bar_window, NULL);
// Window *s = GetWindow(window->title_bar_window); s->kill = true;
// DLL_QUEUE_REMOVE(FirstWindow, LastWindow, s); }
// WindowCount -= 1;
// } if (!window->is_title_bar && window->title_bar_window.id) {
// } Window *s = GetWindow(window->title_bar_window, NULL);
s->kill = true;
}
Dealloc(&window->goto_history);
Dealloc(&window->goto_redo);
Dealloc(allocator, window);
}
View *CreateView(BufferID active_buffer) { View *CreateView(BufferID active_buffer) {
Allocator al = GetSystemAllocator(); Allocator al = GetSystemAllocator();
@@ -204,13 +202,12 @@ View *CreateView(BufferID active_buffer) {
view->active_buffer = active_buffer; view->active_buffer = active_buffer;
view->carets.allocator = al; view->carets.allocator = al;
Add(&view->carets, {0, 0}); Add(&view->carets, {0, 0});
DLL_QUEUE_ADD(FirstView, LastView, view); Add(&Views, view);
ViewCount += 1;
return view; return view;
} }
View *FindView(ViewID view_id, View *default_view = NULL) { View *FindView(ViewID view_id, View *default_view = NULL) {
for (View *it = FirstView; it; it = it->next) { For(Views) {
if (it->id == view_id) { if (it->id == view_id) {
return it; return it;
} }
@@ -219,7 +216,7 @@ View *FindView(ViewID view_id, View *default_view = NULL) {
} }
View *FindView(BufferID buffer_id, View *default_view = NULL) { View *FindView(BufferID buffer_id, View *default_view = NULL) {
for (View *it = FirstView; it; it = it->next) { For(Views) {
if (it->active_buffer == buffer_id) { if (it->active_buffer == buffer_id) {
return it; return it;
} }
@@ -228,7 +225,7 @@ View *FindView(BufferID buffer_id, View *default_view = NULL) {
} }
Window *FindWindow(ViewID view_id, Window *default_window = NULL) { Window *FindWindow(ViewID view_id, Window *default_window = NULL) {
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
if (it->active_view == view_id) { if (it->active_view == view_id) {
return it; return it;
} }
@@ -237,7 +234,7 @@ Window *FindWindow(ViewID view_id, Window *default_window = NULL) {
} }
Window *FindWindow(String buffer_name, Window *default_window = NULL) { Window *FindWindow(String buffer_name, Window *default_window = NULL) {
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
View *it_view = GetView(it->active_view); View *it_view = GetView(it->active_view);
Buffer *it_buffer = GetBuffer(it_view->active_buffer); Buffer *it_buffer = GetBuffer(it_view->active_buffer);
if (it_buffer->name == buffer_name) { if (it_buffer->name == buffer_name) {
@@ -248,7 +245,7 @@ Window *FindWindow(String buffer_name, Window *default_window = NULL) {
} }
Window *FindWindow(BufferID buffer_id) { Window *FindWindow(BufferID buffer_id) {
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
View *view = GetView(it->active_view); View *view = GetView(it->active_view);
if (view->active_buffer == buffer_id) return it; if (view->active_buffer == buffer_id) return it;
} }
@@ -256,7 +253,7 @@ Window *FindWindow(BufferID buffer_id) {
} }
View *FindView(String name, View *default_view = NULL) { View *FindView(String name, View *default_view = NULL) {
for (View *it = FirstView; it; it = it->next) { For(Views) {
Buffer *buffer = GetBuffer(it->active_buffer); Buffer *buffer = GetBuffer(it->active_buffer);
if (buffer->name == name) { if (buffer->name == name) {
return it; return it;
@@ -444,7 +441,7 @@ View *WindowOpenBufferView(Window *new_parent_window, String name) {
} }
bool ViewIsCrumb(ViewID view_id) { bool ViewIsCrumb(ViewID view_id) {
for (Window *window = FirstWindow; window; window = window->next) { ForItem(window, Windows) {
For(window->goto_history) if (it.view_id == view_id) return true; For(window->goto_history) if (it.view_id == view_id) return true;
For(window->goto_redo) if (it.view_id == view_id) return true; For(window->goto_redo) if (it.view_id == view_id) return true;
} }
@@ -460,7 +457,7 @@ bool ViewIsReferenced(ViewID view) {
return true; return true;
} }
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
if (it->active_view == view || it->active_goto_list == view) { if (it->active_view == view || it->active_goto_list == view) {
return true; return true;
} }
@@ -482,7 +479,7 @@ bool BufferIsReferenced(BufferID buffer_id) {
void GarbageCollect() { void GarbageCollect() {
Allocator sys_allocator = GetSystemAllocator(); Allocator sys_allocator = GetSystemAllocator();
for (Buffer *it = FirstBuffer; it; it = it->next) { For(Buffers) {
if (it->file_mod_time) { if (it->file_mod_time) {
int64_t new_file_mod_time = GetFileModTime(it->name); int64_t new_file_mod_time = GetFileModTime(it->name);
if (it->file_mod_time != new_file_mod_time) { if (it->file_mod_time != new_file_mod_time) {
@@ -492,8 +489,8 @@ void GarbageCollect() {
} }
} }
for (View *it = FirstView, *next = NULL; it; it = next) { IterRemove(Views) {
next = it->next; IterRemovePrepare(Views);
Buffer *buffer = GetBuffer(it->active_buffer); Buffer *buffer = GetBuffer(it->active_buffer);
if (!buffer->garbage) { if (!buffer->garbage) {
@@ -505,13 +502,13 @@ void GarbageCollect() {
continue; continue;
} }
DLL_QUEUE_REMOVE(FirstView, LastView, it); remove_item = true;
Dealloc(&it->carets); Dealloc(&it->carets);
Dealloc(sys_allocator, it); Dealloc(sys_allocator, it);
} }
for (Buffer *it = FirstBuffer, *next = NULL; it; it = next) { IterRemove(Buffers) {
next = it->next; IterRemovePrepare(Buffers);
if (!it->garbage) { if (!it->garbage) {
continue; continue;
@@ -522,14 +519,15 @@ void GarbageCollect() {
continue; continue;
} }
DLL_QUEUE_REMOVE(FirstBuffer, LastBuffer, it); remove_item = true;
DeallocBuffer(it); DeallocBuffer(it);
} }
// for (Window *it = FirstWindow, *next = NULL; it; it = next) { IterRemove(Windows) {
// next = it->next; IterRemovePrepare(Windows);
// if (it->kill) { if (it->kill) {
// DestroyWindow(it); DestroyWindow(it);
// } remove_item = true;
// } }
}
} }

View File

@@ -16,7 +16,7 @@ SDL_Window *SDLWindow;
bool IsInFullscreen; bool IsInFullscreen;
int FullScreenSizeX, FullScreenSizeY; int FullScreenSizeX, FullScreenSizeY;
int FullScreenPositionX, FullScreenPositionY; int FullScreenPositionX, FullScreenPositionY;
bool Testing = true; bool Testing = false;
#include "generated_variables.cpp" #include "generated_variables.cpp"
#include "render/generated_font.cpp" #include "render/generated_font.cpp"
@@ -246,7 +246,7 @@ void Update(Event event) {
} }
OnCommand(event); OnCommand(event);
for (Window *it = FirstWindow; it; it = it->next) { For(Windows) {
if (it->is_title_bar) ReplaceTitleBarData(it); if (it->is_title_bar) ReplaceTitleBarData(it);
} }
UpdateProcesses(); UpdateProcesses();

View File

@@ -5,8 +5,6 @@ struct WindowID { Int id; Window *o; };
struct View { struct View {
ViewID id; ViewID id;
BufferID active_buffer; BufferID active_buffer;
View *next;
View *prev;
Vec2I scroll; Vec2I scroll;
Array<Caret> carets; Array<Caret> carets;
@@ -26,8 +24,6 @@ struct GotoCrumb {
struct Window { struct Window {
WindowID id; WindowID id;
ViewID active_view; ViewID active_view;
Window *next;
Window *prev;
WindowSplit *split_ref; WindowSplit *split_ref;
WindowID title_bar_window; WindowID title_bar_window;

View File

@@ -17,8 +17,6 @@ void UpdateDebugBuffer() {
RawAppendf(buffer, "mouse: [%f, %f]\n", xmouse, ymouse); RawAppendf(buffer, "mouse: [%f, %f]\n", xmouse, ymouse);
RawAppendf(buffer, "BufferID id = %d\n", main.buffer->id.id); RawAppendf(buffer, "BufferID id = %d\n", main.buffer->id.id);
RawAppendf(buffer, "Buffer *next = %zu\n", main.buffer->next);
RawAppendf(buffer, "Buffer *prev = %zu\n", main.buffer->prev);
RawAppendf(buffer, "String name = %S\n", main.buffer->name); RawAppendf(buffer, "String name = %S\n", main.buffer->name);
RawAppendf(buffer, "Int change_id = %lld\n", (long long)main.buffer->change_id); RawAppendf(buffer, "Int change_id = %lld\n", (long long)main.buffer->change_id);
RawAppendf(buffer, "Int user_change_id = %lld\n", (long long)main.buffer->user_change_id); RawAppendf(buffer, "Int user_change_id = %lld\n", (long long)main.buffer->user_change_id);

View File

@@ -1,8 +1,8 @@
Array<Window *> GetWindowZOrder(Allocator allocator) { Array<Window *> GetWindowZOrder(Allocator allocator) {
Array<Window *> order = {allocator}; Array<Window *> order = {allocator};
for (Window *it = FirstWindow; it; it = it->next) if (it->z == 2) Add(&order, it); For(Windows) if (it->z == 2) Add(&order, it);
for (Window *it = FirstWindow; it; it = it->next) if (it->z == 1) Add(&order, it); For(Windows) if (it->z == 1) Add(&order, it);
for (Window *it = FirstWindow; it; it = it->next) if (it->z == 0) Add(&order, it); For(Windows) if (it->z == 0) Add(&order, it);
return order; return order;
} }