Improve GC

This commit is contained in:
Krzosa Karol
2024-08-13 16:02:22 +02:00
parent 40cb8582fd
commit f125a38c50
8 changed files with 110 additions and 54 deletions

View File

@@ -86,13 +86,22 @@ void IKnowWhatImDoing_ApplyEdits(Buffer *buffer, Array<Edit> &edits) {
IKnowWhatImDoing__ApplyEditsMultiCursor(buffer, edits);
}
void ClearRedoStack(Buffer *buffer) {
ForItem(entry, buffer->redo_stack) {
Dealloc(&entry.carets);
ForItem(edit, entry.edits) Dealloc(entry.edits.allocator, &edit.string.data);
Dealloc(&entry.edits);
void DeallocHistoryEntries(Array<HistoryEntry> *entries) {
For(*entries) {
Dealloc(&it.carets);
ForItem(edit, it.edits) Dealloc(it.edits.allocator, &edit.string.data);
Dealloc(&it.edits);
}
buffer->redo_stack.len = 0;
entries->len = 0;
}
void ClearRedoStack(Buffer *buffer) {
DeallocHistoryEntries(&buffer->redo_stack);
}
void DeallocHistoryArray(Array<HistoryEntry> *entries) {
DeallocHistoryEntries(entries);
Dealloc(entries);
}
// @note: !!

View File

@@ -162,8 +162,10 @@ void Command_ListBuffers() {
String result = Merge(scratch, strings, "\n");
String16 string16 = ToString16(scratch, result);
String buffer_name = GetUniqueBufferName(scratch, GetDir(main.buffer), "+list_buffers-");
View *new_view = WindowOpenBufferView(main.window, buffer_name);
String buffer_name = GetUniqueBufferName(scratch, GetDir(main.buffer), "+list_buffers-");
View *new_view = WindowOpenBufferView(main.window, buffer_name);
Buffer *new_buffer = GetBuffer(new_view->active_buffer);
new_buffer->gc = true;
Command_SelectEntireBuffer(new_view);
Command_Replace(new_view, string16);
@@ -236,6 +238,12 @@ void Command_Append(View *view, String string, bool scroll_to_end_if_cursor_on_l
Command_Append(view, string16, scroll_to_end_if_cursor_on_last_line);
}
void Command_Appendf(View *view, const char *fmt, ...) {
Scratch scratch;
STRING_FORMAT(scratch, fmt, string);
Command_Append(view, string, true);
}
void ReportErrorf(const char *fmt, ...) {
Scratch scratch;
STRING_FORMAT(scratch, fmt, string);

View File

@@ -23,8 +23,9 @@ void ExecInNewBuffer(String cmd, String working_dir) {
View *view = WindowOpenBufferView(main.window, buffer_name);
Buffer *buffer = GetBuffer(view->active_buffer);
buffer->gc = true;
Command_SelectRangeOneCursor(view, Rng(0));
view->carets[0] = MakeCaret({});
Exec(view->id, false, cmd, working_dir);
ActiveWindow = main.window->id;
}
@@ -92,7 +93,7 @@ int Lua_AppendCmd(lua_State *L) {
return 0;
}
int Lua_NewCmd(lua_State *L) {
int Lua_C(lua_State *L) {
String string = lua_tostring(L, 1);
lua_pop(L, 1);

View File

@@ -1,7 +1,7 @@
luaL_Reg LuaFunctions[] = {
{"FuzzySort", Lua_FuzzySort},
{"AppendCmd", Lua_AppendCmd},
{"NewCmd", Lua_NewCmd},
{"C", Lua_C},
{"Kill", Lua_Kill},
{"Open", Lua_Open},
{"Print", Lua_Print},

View File

@@ -6,7 +6,6 @@ Array<BufferID> Buffers = {};
Array<ViewID> Views = {};
Array<WindowID> Windows = {};
WindowID NullWindowID;
BufferID NullBufferID; // +buffer
ViewID NullViewID;
@@ -20,12 +19,18 @@ 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; }
View *GCInfoView;
Buffer *GCInfoBuffer;
void InitScratchBuffer() {
Allocator sys_allocator = GetSystemAllocator();
Buffer *null_buffer = CreateBuffer(sys_allocator, BuffCWD("+console"));
View *null_view = CreateView(null_buffer->id);
Assert(null_buffer->id == NullBufferID && null_view->id == NullViewID);
GCInfoBuffer = CreateBuffer(sys_allocator, BuffCWD("+gc"));
GCInfoView = CreateView(GCInfoBuffer->id);
}
inline bool IsDocumentSelectionValid() {
if (DocumentSelected.id == -1) return false;
@@ -73,7 +78,13 @@ inline View *GetView(ViewID id) {
inline bool IsNull(Buffer *buffer) { return buffer->id.id == NullBufferID.id; }
inline Window *GetActiveWindow() { return GetWindow(ActiveWindow); }
// inline View *GetActiveView(Window *window) { return GetView(window->active_view); }
String BuffCWD(String string) {
Scratch scratch;
String result = Format(scratch, "%.*s/%.*s", FmtString(WorkingDir), FmtString(string));
result = Intern(&GlobalInternTable, result);
return result;
}
void InitBuffer(Allocator allocator, Buffer *buffer, String name, Int size = 4096) {
buffer->id = AllocBufferID(buffer);
@@ -86,7 +97,7 @@ void InitBuffer(Allocator allocator, Buffer *buffer, String name, Int size = 409
Add(&buffer->line_starts, (Int)0);
}
Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096) {
Buffer *CreateBuffer(Allocator allocator, String name, Int size) {
Buffer *result = AllocType(allocator, Buffer);
InitBuffer(allocator, result, name, size);
Add(&Buffers, result->id);
@@ -336,48 +347,68 @@ View *WindowOpenBufferView(Window *new_parent_window, String name) {
return result;
}
bool ViewIsReferenced(ViewID view) {
Window *ViewIsReferenced(ViewID view) {
For(Windows) {
Window *window = it.o;
if (window->active_view == view) return true;
if (window->active_goto_list == view) return true;
if (window->active_view == view) return window;
if (window->active_goto_list == view) return window;
}
return false;
return NULL;
}
bool BufferIsReferenced(BufferID buffer_id) {
if (buffer_id == NullBufferID) return true;
if (buffer_id == DebugBufferID) return true;
if (buffer_id == LuaBufferID) return true;
View *BufferIsReferenced(BufferID buffer_id) {
For(Views) {
View *view = it.o;
if (view->active_buffer == buffer_id) return true;
if (view->active_buffer == buffer_id) return view;
}
return false;
return NULL;
}
Window *BufferIsCrumb(BufferID buffer_id) {
For(Windows) {
Window *window = it.o;
For(window->goto_history) if (it.buffer_id == buffer_id) return window;
For(window->goto_redo) if (it.buffer_id == buffer_id) return window;
}
return NULL;
}
void GarbageCollect() {
IterRemove(Views) {
IterRemovePrepare(Views);
View *view = it.o;
if (!ViewIsReferenced(view->id)) {
View *view = it.o;
Buffer *buffer = GetBuffer(view->active_buffer);
bool gc = buffer->gc || buffer->is_directory;
Window *ref = ViewIsReferenced(view->id);
if (gc && !ref) {
Dealloc(&view->carets);
// @todo: add view to free list
remove_item = true;
// @todo: add view to free list
Command_Appendf(GCInfoView, "view %.*s", FmtString(buffer->name));
}
}
IterRemove(Buffers) {
IterRemovePrepare(Buffers);
Buffer *buffer = it.o;
if (!BufferIsReferenced(buffer->id)) {
bool gc = buffer->gc;
if (buffer->is_directory) {
Window *ref = BufferIsCrumb(buffer->id);
if (!ref) gc = true;
}
View *ref = BufferIsReferenced(buffer->id);
if (gc && !ref) {
Dealloc(&buffer->line_starts);
Dealloc(&buffer->undo_stack);
Dealloc(&buffer->redo_stack);
DeallocHistoryArray(&buffer->undo_stack);
DeallocHistoryArray(&buffer->redo_stack);
Dealloc(buffer->line_starts.allocator, &buffer->data);
// @todo: add buffer to free list
remove_item = true;
ReportConsolef("collected = %.*s", FmtString(buffer->name));
// @todo: add buffer to free list
Command_Appendf(GCInfoView, "buffer %.*s", FmtString(buffer->name));
}
}
}

View File

@@ -37,9 +37,12 @@ struct Buffer {
Array<HistoryEntry> undo_stack;
Array<HistoryEntry> redo_stack;
int edit_phase;
bool no_history;
bool dirty;
bool is_directory;
struct {
int no_history : 1;
int dirty : 1;
int is_directory : 1;
int gc : 1;
};
};
struct View {
@@ -139,6 +142,18 @@ void Command_ReplaceWithoutMovingCarets(View *view, Range range, String16
void ReportConsolef(const char *fmt, ...);
void ReportErrorf(const char *fmt, ...);
void ReportWarningf(const char *fmt, ...);
void Command_Appendf(View *view, const char *fmt, ...);
String BuffCWD(String string);
Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096);
View *CreateView(BufferID active_buffer);
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; }
#if DEBUG_BUILD
#define IF_DEBUG(x) x

View File

@@ -11,6 +11,10 @@
- Find matches using grep, change things in that buffer then apply those changes to all items
- group history entries so the you can rollback through multiple ones at once and not waste time on skipping whitespace trimming or deleting every character
- Check if file exists in ApplyRules otherwise return null
- Different buffers should be GCed differently
- Special buffers that store metadata
- OnWindowCommand allow config user to overwrite the WindowCommand keybinding, introduce his own
- some split selection commands
@@ -20,6 +24,7 @@
- word complete
- Search all buffers in 10X style, incrementally searched results popping up on every key press (maybe we need coroutine library in C so this is easier?)
- To implement that I think it would be best to load all files into memory
- Search and replace
- kill view - killing all views for buffer ejects buffer (maybe also introduce kill buffer)

View File

@@ -120,19 +120,6 @@ bool ToggleVisibility(WindowID window_id) {
return visible;
}
String BuffCWD(String string) {
Scratch scratch;
String result = Format(scratch, "%.*s/%.*s", FmtString(WorkingDir), FmtString(string));
result = Intern(&GlobalInternTable, result);
return result;
}
void InitScratchBuffer() {
Allocator sys_allocator = GetSystemAllocator();
Buffer *null_buffer = CreateBuffer(sys_allocator, BuffCWD("+console"));
View *null_view = CreateView(null_buffer->id);
}
void InitWindows() {
Allocator sys_allocator = Perm;
#if !ARRAY_DEBUG