more cleaning up

This commit is contained in:
Matthew 2026-06-27 12:21:14 +10:00
parent 5261118dd0
commit d3abcbc146
4 changed files with 223 additions and 112 deletions

@ -1 +1 @@
Subproject commit f3d1f551ccfa37de73d626479252bada0fc17cb2 Subproject commit a12e8c21e21b65e16af06675b6c2d1696e23bfa7

View File

@ -8,6 +8,14 @@ import std.math.algebraic : abs;
import editor; import editor;
import buffer : Reset; import buffer : Reset;
enum BufferFlags
{
None = 0x0000,
NoFile = 0x0001,
Modified = 0x0002,
Fixed = 0x0004,
} alias BFRF = BufferFlags;
struct FlatBuffer struct FlatBuffer
{ {
Tokenizer tokenizer; Tokenizer tokenizer;
@ -22,9 +30,53 @@ struct FlatBuffer
Line[] lines; Line[] lines;
u64 line_count; u64 line_count;
bool fixed; BufferFlags flags;
bool changed;
FlatBuffer* list_next; FlatBuffer* list_next;
void
FreeBuffer()
{
Free(this.data);
Free(&this.arena);
Free(&this.line_start_arena);
Free(cast(char*)this.file_name.ptr);
Free(&this.linebufs.arena);
Free(this.tokenizer.tokens);
Free(&this.tokenizer.arena);
memset(&this, 0, FlatBuffer.sizeof);
}
void
Overwrite(FlatBuffer* src)
{
string file_name = ScratchAlloc(this.file_name);
this.FreeBuffer();
this.LoadBuffer(src.data, file_name);
}
void
LoadBuffer(u8[] data, string file_name)
{
u64 capacity = data.length > 0 ? RoundUp(cast(u64)(data.length)*2, KB(4)) : KB(4);
u8[] buffer = Alloc!(u8)(capacity);
MemCpy(buffer.ptr, data.ptr, data.length);
this.arena = CreateArena(MB(1));
this.line_start_arena = CreateArena(KB(512));
this.file_name = file_name;
this.line_count = CountLF(data);
this.length = data.length;
this.linebufs = CreateLineBuffers(MB(1));
this.data = buffer;
this.tokenizer = CreateTokenizer(&this);
Fix(&this);
}
} }
struct BufferViewInfo struct BufferViewInfo
@ -115,33 +167,21 @@ const u64 BUF_START = 1;
FlatBuffer* FlatBuffer*
CreateFlatBuffer(ref Ctx ctx, u8[] data = [], string file_name = "") CreateFlatBuffer(ref Ctx ctx, u8[] data = [], string file_name = "")
{
FlatBuffer* buffer = ctx.free_text_buffers;
if(!buffer)
{ {
if(ctx.text_buffer_count == ctx.text_buffers.length) if(ctx.text_buffer_count == ctx.text_buffers.length)
{ {
ctx.text_buffers = Realloc(ctx.text_buffers, ctx.text_buffers.length+ARRAY_COUNT_INCREMENT); ctx.text_buffers = Realloc(ctx.text_buffers, ctx.text_buffers.length+ARRAY_COUNT_INCREMENT);
} }
FlatBuffer* fb = &ctx.text_buffers[ctx.text_buffer_count++]; buffer = &ctx.text_buffers[ctx.text_buffer_count++];
}
fb.arena = CreateArena(MB(1)); buffer.LoadBuffer(data, file_name);
fb.line_start_arena = CreateArena(KB(512));
u64 capacity = data.length > 0 ? RoundUp(cast(u64)(data.length)*2, KB(4)) : KB(4); return buffer;
u8[] buffer = Alloc!(u8)(capacity);
MemCpy(buffer.ptr, data.ptr, data.length);
fb.file_name = file_name;
fb.line_count = CountLF(data);
fb.length = data.length;
fb.linebufs = CreateLineBuffers(MB(1));
fb.data = buffer;
fb.tokenizer = CreateTokenizer(fb);
Fix(fb);
return fb;
} }
void void
@ -216,31 +256,19 @@ ResetViewInfo(BufferViewInfo* info)
info.selection_mode = SM.None; info.selection_mode = SM.None;
info.pos = 0; info.pos = 0;
info.column_position = 0; info.column_position = 0;
info.line_offset = 0;
} }
/*
void
Change(FlatBuffer* fb, u8[] data, string file_name)
{
Free(fb.data);
Reset(&fb.linebufs.arena);
Init(fb, data, file_name);
ResetTokenizer(&fb.tk, fb.data.length);
Fix(fb);
}
*/
u64 u64
CountLF(u8[] data) CountLF(u8[] data)
{ {
u64 lf_count = 1; u64 line_feed_count = 1;
for(u64 i = 0; i < data.length; i += 1) for(u64 i = 0; i < data.length; i += 1)
{ {
lf_count += u64(data.ptr[i] == '\n'); line_feed_count += u64(data.ptr[i] == '\n');
} }
return lf_count; return line_feed_count;
} }
pragma(inline, true) bool pragma(inline, true) bool
@ -330,7 +358,7 @@ Fix(T)(T* buffer)
buffer.lines[buffer.line_count-1].length = buffer.length - buffer.lines[buffer.line_count-1].pos; buffer.lines[buffer.line_count-1].length = buffer.length - buffer.lines[buffer.line_count-1].pos;
buffer.fixed = true; buffer.flags &= BFRF.Fixed;
TokenizeD(buffer); TokenizeD(buffer);
} }
@ -344,7 +372,7 @@ CreateLineBuffers(u64 arena_size)
void void
Insert(Editor* editor, u8[] insert, u64 length, u64 insert_position) Insert(Editor* editor, u8[] insert, u64 length, u64 insert_position)
{ {
editor.changed = true; editor.flags &= BFRF.Modified;
if(editor.length + length > editor.data.length-SPACING) if(editor.length + length > editor.data.length-SPACING)
{ {

View File

@ -15,7 +15,9 @@ import std.stdio;
import std.exception; import std.exception;
import std.file; import std.file;
import std.string; import std.string;
import core.stdc.stdio; import core.stdc.stdio : File = FILE, FOpen = fopen, FFlush = fflush, FWrite = fwrite, FSeek = fseek, FTell = ftell, FClose = fclose, FRead = fread, SeekSet = SEEK_SET, SeekEnd = SEEK_END;
// TODO: add function for moving data within text buffer using SIMD and moving in batches that fit within CPU cache
const u64 ARRAY_COUNT_INCREMENT = 32; const u64 ARRAY_COUNT_INCREMENT = 32;
@ -101,6 +103,7 @@ struct Ctx
FlatBuffer[] text_buffers; FlatBuffer[] text_buffers;
u64 text_buffer_count; u64 text_buffer_count;
FlatBuffer* free_text_buffers; FlatBuffer* free_text_buffers;
u64 new_buffer_count; // files that are not yet files (you know)
@property ref DescSet desc_set() => this.rd_ctx.desc_sets[this.frame_index]; @property ref DescSet desc_set() => this.rd_ctx.desc_sets[this.frame_index];
@ -257,7 +260,7 @@ const Command NO_CMD = {
type: CT.None, type: CT.None,
}; };
Command[21] CMD_LIST = [ Command[22] CMD_LIST = [
{ {
name: "Open", name: "Open",
cmd: "open", cmd: "open",
@ -268,14 +271,21 @@ Command[21] CMD_LIST = [
{ {
name: "Save", name: "Save",
cmd: "save", cmd: "save",
desc: "Save the current file in the focused editor view.", desc: "Save the current file.",
type: CT.Callback, type: CT.Callback,
fn: &SaveFileWindow, fn: &CmdSaveFile,
},
{
name: "Save As",
cmd: "save as",
desc: "Save the current file as a specified name.",
type: CT.Callback,
fn: &CmdSaveFileWindow,
}, },
{ {
name: "New File", name: "New File",
cmd: "new file", cmd: "new file",
desc: "Create a new file with a specified name and location.", desc: "Open an empty buffer",
type: CT.Callback, type: CT.Callback,
fn: &NotImplementedCallback, fn: &NotImplementedCallback,
}, },
@ -595,36 +605,34 @@ InitCtx(PlatformWindow* window)
} }
} }
void bool
SaveFile(Editor* ed, string file_name) SaveBufferToFile(Editor* editor)
{ {
import core.stdc.stdio; bool saved;
file_name = file_name.length == 0 ? Str(ed.file_name) : file_name; assert(editor.buffer);
assert(editor.file_name.length);
if(file_name.length > 0) auto f = FOpen(editor.file_name.ptr, "wb");
{
string file_path = AbsolutePath(file_name);
auto f = fopen(cast(char*)file_path.ptr, "wb");
if(f != null) if(f != null)
{ {
u64 tab_count; u64 tab_count;
for(u64 i = 0; i < ed.length; i += 1) for(u64 i = 0; i < editor.length; i += 1)
{ {
if(ed.data[i] == '\t') if(editor.data[i] == '\t')
{ {
tab_count += 1; tab_count += 1;
} }
} }
u64 tab_width = GetCtx().tab_width; u64 tab_width = GetCtx().tab_width;
u64 buf_size = ed.length + ((tab_width-1) * tab_count); u64 buffer_size = editor.length + ((tab_width-1) * tab_count);
u8[] temp_buf = ScratchAlloc!(u8)(buf_size); u8[] temp_buf = ScratchAlloc!(u8)(buffer_size);
u64 buf_pos; u64 buf_pos;
for(u64 i = 0; i < ed.length; i += 1) for(u64 i = 0; i < editor.length; i += 1)
{ {
if(ed.data[i] == '\t') if(editor.data[i] == '\t')
{ {
for(u64 j = 0; j < tab_width; j += 1) for(u64 j = 0; j < tab_width; j += 1)
{ {
@ -633,15 +641,18 @@ SaveFile(Editor* ed, string file_name)
} }
else else
{ {
temp_buf[buf_pos++] = ed.data[i]; temp_buf[buf_pos++] = editor.data[i];
} }
} }
fwrite(temp_buf.ptr, 1, buf_size, f); FWrite(temp_buf.ptr, 1, buffer_size, f);
fflush(f); FFlush(f);
fclose(f); FClose(f);
}
saved = true;
} }
return saved;
} }
string string

View File

@ -335,6 +335,14 @@ struct Rect
}; };
}; };
this(Vec2 p0, Vec2 p1)
{
this.v[0].x = p0.x;
this.v[0].y = p0.y;
this.v[1].x = p1.x;
this.v[1].y = p1.y;
}
ref Vec2 opIndex(usize index) ref Vec2 opIndex(usize index)
{ {
return this.v[index]; return this.v[index];
@ -344,8 +352,28 @@ struct Rect
{ {
return this.v[index] = value; return this.v[index] = value;
} }
Rect opBinary(string op)(Rect rhs)
if(op == "*" || op == "+" || op == "-" || op == "+" || op == "/")
{
Rect result;
static foreach(i; 0 .. this.v.length)
{
mixin("result.v[", i, "].x = this.v[", i, "].x"~op~"rhs.v[", i, "].x;");
mixin("result.v[", i, "].y = this.v[", i, "].y"~op~"rhs.v[", i, "].y;");
} }
return result;
}
}
Rect RectX0(f32 value) => Rect(Vec2(value, 0.0), Vec2(0.0, 0.0));
Rect RectY0(f32 value) => Rect(Vec2(0.0, value), Vec2(0.0, 0.0));
Rect RectX1(f32 value) => Rect(Vec2(0.0, 0.0), Vec2(value, 0.0));
Rect RectY1(f32 value) => Rect(Vec2(0.0, 0.0), Vec2(0.0, value));
Rect RectXY0(f32 x, f32 y) => Rect(Vec2(x, y), Vec2(0.0, 0.0));
Rect RectXY1(f32 x, f32 y) => Rect(Vec2(0.0, 0.0), Vec2(x, y));
alias UIHash = u64; alias UIHash = u64;
alias UIPair = KVPair!(UIHash, UIItem*); alias UIPair = KVPair!(UIHash, UIItem*);
@ -1029,24 +1057,40 @@ SearchInputWindow(T)(string hash_text, SearchWindowCtx!(T)* window_ctx, bool rea
} }
bool bool
SaveFileWindow(ref Ctx ctx) CmdSaveFile(ref Ctx ctx)
{
bool result = true;
Editor* editor = ctx.focused_panel.ed;
if(editor.file_name.length)
{
SaveBufferToFile(editor);
}
else
{
result = CmdSaveFileWindow(ctx);
}
return result;
}
bool
CmdSaveFileWindow(ref Ctx ctx)
{ {
bool exit; bool exit;
Editor* ed = ctx.focused_panel.ed; Editor* editor = ctx.focused_panel.ed;
static bool init = false; static bool init = false;
if(!init) if(!init)
{ {
ctx.cmd.exec_cmd_input.data[0 .. ed.file_name.length] = Arr!(u8)(ed.file_name[0 .. $]); ctx.cmd.exec_cmd_input.data[0 .. editor.file_name.length] = Arr!(u8)(editor.file_name[0 .. $]);
ctx.cmd.exec_cmd_input.length = ed.file_name.length; ctx.cmd.exec_cmd_input.length = editor.file_name.length;
} }
const PAD = 4.0f; const PAD = 4.0f;
Vec2 extent = GetExtent(); Vec2 extent = GetExtent();
// TODO: fix: This breaks when setting GetFontSet input to not 12, probably incorrect draw call boundaries (again) FontSet* fs = GetFontSet(14);
FontSet* fs = GetFontSet(12);
f32 x = extent.x * 0.1; f32 x = extent.x * 0.1;
f32 w = extent.x * 0.8; f32 w = extent.x * 0.8;
@ -1072,8 +1116,7 @@ SaveFileWindow(ref Ctx ctx)
DrawRect(ctx, inner_rect, &CMD_STYLE); DrawRect(ctx, inner_rect, &CMD_STYLE);
Rect text_rect = inner_rect; Rect text_rect = inner_rect + RectX0(PAD);
text_rect.p0.x += PAD;
DrawText(ctx, Str(ctx.cmd.exec_cmd_input), WHITE, fs, text_rect, TA.Left, -1); DrawText(ctx, Str(ctx.cmd.exec_cmd_input), WHITE, fs, text_rect, TA.Left, -1);
DrawBorder(ctx, inner_rect, &CMD_STYLE); DrawBorder(ctx, inner_rect, &CMD_STYLE);
@ -1087,12 +1130,41 @@ SaveFileWindow(ref Ctx ctx)
{ {
case Enter: case Enter:
{ {
SaveFile(ed, Str(ctx.cmd.exec_cmd_input)); if(!ctx.cmd.exec_cmd_input.length) break;
} goto case;
case Escape: // TODO: continue here, create new flat buffer then put in new save function
string file_name = AbsolutePath(Str(ctx.cmd.exec_cmd_input));
if(file_name != editor.file_name)
{ {
exit = taken = true; bool found;
} break; foreach(i; 0 .. ctx.text_buffer_count)
{
if(file_name == ctx.text_buffers[i].file_name)
{
ctx.text_buffers[i].Overwrite(editor.buffer);
editor.buffer = &ctx.text_buffers[i];
found = true;
break;
}
}
if(!found)
{
editor.buffer = CreateFlatBuffer(ctx, editor.buffer.data, file_name);
}
}
if(SaveBufferToFile(editor))
{
editor.flags &= ~(BFRF.Modified & BFRF.NoFile);
}
else
{
// TODO: show error..
}
} goto case;
case Escape: exit = taken = true; break;
default: taken = HandleTextInput(&ctx.cmd.exec_cmd_input, ev); break; default: taken = HandleTextInput(&ctx.cmd.exec_cmd_input, ev); break;
} }
} }