fix some stuff that breaks on windows

memory-refactor
Patrick Cleavelin 2025-02-08 14:03:48 -06:00
parent 111f2f8a70
commit f0eae25439
9 changed files with 143 additions and 103 deletions

1
build.bat Normal file
View File

@ -0,0 +1 @@
..\odin\odin.exe build src/ -out:bin\editor.exe -debug

View File

@ -1,6 +1,7 @@
use std::{
borrow::Cow,
ffi::{c_char, c_void, CStr},
ffi::{c_char, c_void, CStr, CString},
fmt::write,
path::Path,
};
@ -133,8 +134,11 @@ impl BufferVTable {
}
}
pub fn open_buffer(&self, path: impl AsRef<Path>, line: i32, col: i32) {
let c_str = path.as_ref().to_string_lossy().as_ptr();
(self.open_buffer)(c_str, line as isize, col as isize);
let Ok(c_str) = CString::new(path.as_ref().as_os_str().as_encoded_bytes()) else {
eprintln!("grep plugin failed to open buffer");
return;
};
(self.open_buffer)(c_str.as_ptr() as *const u8, line as isize, col as isize);
}
pub fn open_virtual_buffer(&self) -> Buffer {
Buffer {

View File

@ -1,7 +1,7 @@
// The default syntax highlighter plugin for Odin & Rust
package highlighter;
import "core:runtime"
import "base:runtime"
import "core:fmt"
import p "../../../src/plugin"

View File

@ -1,6 +1,6 @@
package core
import "core:runtime"
import "base:runtime"
import "core:reflect"
import "core:fmt"
import "core:log"
@ -97,6 +97,10 @@ current_buffer :: proc(state: ^State) -> ^FileBuffer {
return &state.log_buffer;
}
if len(state.buffers) < 1 {
return nil
}
return &state.buffers[state.current_buffer];
}
@ -167,7 +171,7 @@ new_input_actions :: proc() -> InputActions {
return input_actions;
}
delete_input_map :: proc(input_map: ^InputMap) {
for _, &actions in &input_map.mode {
for _, &actions in input_map.mode {
delete_input_actions(&actions);
}
delete(input_map.mode);

View File

@ -1,6 +1,6 @@
package core;
import "core:runtime"
import "base:runtime"
ErrorType :: enum {
None,

View File

@ -6,7 +6,7 @@ import "core:mem"
import "core:fmt"
import "core:math"
import "core:slice"
import "core:runtime"
import "base:runtime"
import "core:strings"
import "../theme"
@ -672,8 +672,10 @@ new_virtual_file_buffer :: proc(allocator: mem.Allocator) -> FileBuffer {
new_file_buffer :: proc(allocator: mem.Allocator, file_path: string, base_dir: string = "") -> (FileBuffer, Error) {
context.allocator = allocator;
fmt.eprintln("attempting to open", file_path);
fd, err := os.open(file_path);
if err != os.ERROR_NONE {
if err != nil {
return FileBuffer{}, make_error(ErrorType.FileIOError, fmt.aprintf("failed to open file: errno=%x", err));
}
defer os.close(fd);
@ -696,10 +698,12 @@ new_file_buffer :: proc(allocator: mem.Allocator, file_path: string, base_dir: s
width := 256;
height := 256;
fmt.eprintln("file path", fi.fullpath[4:]);
buffer := FileBuffer {
allocator = allocator,
directory = dir,
file_path = fi.fullpath,
file_path = fi.fullpath[4:],
extension = extension,
original_content = slice.clone_to_dynamic(original_content),
@ -951,7 +955,6 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, sho
draw_rect(state, sel_x, text_y, width, state.source_font_height, .Green);
}
}
}

View File

@ -26,6 +26,7 @@ gen_font_atlas :: proc(state: ^State, path: cstring) -> FontAtlas {
// FIXME: check if this failed
font = ttf.OpenFont(path, font_height),
}
assert(atlas.font != nil);
ttf.SetFontStyle(atlas.font, ttf.STYLE_NORMAL);
// NOTE: not sure if I like the look of this or not yet

View File

@ -1,10 +1,11 @@
package main
import "core:c"
import "core:os"
import "core:path/filepath"
import "core:math"
import "core:strings"
import "core:runtime"
import "base:runtime"
import "core:fmt"
import "core:log"
import "core:mem"
@ -18,6 +19,8 @@ import "theme"
import "ui"
import "plugin"
HardcodedFontPath :: "bin/BerkeleyMono-Regular.ttf";
State :: core.State;
FileBuffer :: core.FileBuffer;
@ -146,7 +149,7 @@ register_default_input_actions :: proc(input_map: ^core.InputActions) {
state.source_font_height -= 2;
state.source_font_width = state.source_font_height / 2;
state.font_atlas = core.gen_font_atlas(state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
state.font_atlas = core.gen_font_atlas(state, HardcodedFontPath);
}
log.debug(state.source_font_height);
}, "increase font size");
@ -154,7 +157,7 @@ register_default_input_actions :: proc(input_map: ^core.InputActions) {
state.source_font_height += 2;
state.source_font_width = state.source_font_height / 2;
state.font_atlas = core.gen_font_atlas(state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
state.font_atlas = core.gen_font_atlas(state, HardcodedFontPath);
}, "decrease font size");
}
@ -286,10 +289,10 @@ ui_font_height :: proc() -> i32 {
}
draw :: proc(state_with_ui: ^StateWithUi) {
buffer := core.current_buffer(state_with_ui.state);
if buffer := core.current_buffer(state_with_ui.state); buffer != nil {
buffer.glyph_buffer_height = math.min(256, int((state_with_ui.state.screen_height - state_with_ui.state.source_font_height*2) / state_with_ui.state.source_font_height)) + 1;
buffer.glyph_buffer_width = math.min(256, int((state_with_ui.state.screen_width - state_with_ui.state.source_font_width) / state_with_ui.state.source_font_width));
}
render_color := theme.get_palette_color(.Background);
sdl2.SetRenderDrawColor(state_with_ui.state.sdl_renderer, render_color.r, render_color.g, render_color.b, render_color.a);
@ -832,6 +835,8 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
open_buffer = proc "c" (path: cstring, line: int, col: int) {
context = state.ctx;
fmt.eprintln("opening file from dll", path)
path := string(path);
should_create_buffer := true;
for buffer, index in state.buffers {
@ -1106,7 +1111,7 @@ main :: proc() {
sdl_window := sdl2.CreateWindow(
"odin_editor - [now with more ui]",
sdl2.WINDOWPOS_UNDEFINED,
0,
sdl2.WINDOWPOS_UNDEFINED,
640,
480,
{.SHOWN, .RESIZABLE, .ALLOW_HIGHDPI}
@ -1129,7 +1134,7 @@ main :: proc() {
log.error("Failed to create renderer:", sdl2.GetError());
return;
}
state.font_atlas = core.gen_font_atlas(&state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
state.font_atlas = core.gen_font_atlas(&state, HardcodedFontPath);
defer {
if state.font_atlas.font != nil {
ttf.CloseFont(state.font_atlas.font);
@ -1170,9 +1175,29 @@ main :: proc() {
}
// **********************************************************************
L := lua.L_newstate();
state.L = L;
lua.L_openlibs(L);
lua_allocator :: proc "c" (ud: rawptr, ptr: rawptr, osize, nsize: c.size_t) -> (buf: rawptr) {
old_size := int(osize)
new_size := int(nsize)
context = (^runtime.Context)(ud)^
if ptr == nil {
data, err := runtime.mem_alloc(new_size)
return raw_data(data) if err == .None else nil
} else {
if nsize > 0 {
data, err := runtime.mem_resize(ptr, old_size, new_size)
return raw_data(data) if err == .None else nil
} else {
runtime.mem_free(ptr)
return
}
}
}
_context := context;
// L := lua.newstate(lua_allocator, &_context);
// L := lua.L_newstate();
state.L = lua.L_newstate();
lua.L_openlibs(state.L);
bbb: [^]lua.L_Reg;
editor_lib := [?]lua.L_Reg {
@ -1780,93 +1805,93 @@ main :: proc() {
};
// TODO: generate this from the plugin.Key enum
lua.newtable(L);
lua.newtable(state.L);
{
lua.newtable(L);
lua.pushinteger(L, lua.Integer(plugin.Key.B));
lua.setfield(L, -2, "B");
lua.newtable(state.L);
lua.pushinteger(state.L, lua.Integer(plugin.Key.B));
lua.setfield(state.L, -2, "B");
lua.pushinteger(L, lua.Integer(plugin.Key.T));
lua.setfield(L, -2, "T");
lua.pushinteger(state.L, lua.Integer(plugin.Key.T));
lua.setfield(state.L, -2, "T");
lua.pushinteger(L, lua.Integer(plugin.Key.Y));
lua.setfield(L, -2, "Y");
lua.pushinteger(state.L, lua.Integer(plugin.Key.Y));
lua.setfield(state.L, -2, "Y");
lua.pushinteger(L, lua.Integer(plugin.Key.P));
lua.setfield(L, -2, "P");
lua.pushinteger(state.L, lua.Integer(plugin.Key.P));
lua.setfield(state.L, -2, "P");
lua.pushinteger(L, lua.Integer(plugin.Key.M));
lua.setfield(L, -2, "M");
lua.pushinteger(state.L, lua.Integer(plugin.Key.M));
lua.setfield(state.L, -2, "M");
lua.pushinteger(L, lua.Integer(plugin.Key.K));
lua.setfield(L, -2, "K");
lua.pushinteger(state.L, lua.Integer(plugin.Key.K));
lua.setfield(state.L, -2, "K");
lua.pushinteger(L, lua.Integer(plugin.Key.J));
lua.setfield(L, -2, "J");
lua.pushinteger(state.L, lua.Integer(plugin.Key.J));
lua.setfield(state.L, -2, "J");
lua.pushinteger(L, lua.Integer(plugin.Key.Q));
lua.setfield(L, -2, "Q");
lua.pushinteger(state.L, lua.Integer(plugin.Key.Q));
lua.setfield(state.L, -2, "Q");
lua.pushinteger(L, lua.Integer(plugin.Key.BACKQUOTE));
lua.setfield(L, -2, "Backtick");
lua.pushinteger(state.L, lua.Integer(plugin.Key.BACKQUOTE));
lua.setfield(state.L, -2, "Backtick");
lua.pushinteger(L, lua.Integer(plugin.Key.ESCAPE));
lua.setfield(L, -2, "Escape");
lua.pushinteger(state.L, lua.Integer(plugin.Key.ESCAPE));
lua.setfield(state.L, -2, "Escape");
lua.pushinteger(L, lua.Integer(plugin.Key.ENTER));
lua.setfield(L, -2, "Enter");
lua.pushinteger(state.L, lua.Integer(plugin.Key.ENTER));
lua.setfield(state.L, -2, "Enter");
lua.pushinteger(L, lua.Integer(plugin.Key.SPACE));
lua.setfield(L, -2, "Space");
lua.pushinteger(state.L, lua.Integer(plugin.Key.SPACE));
lua.setfield(state.L, -2, "Space");
}
lua.setfield(L, -2, "Key");
lua.setfield(state.L, -2, "Key");
{
lua.newtable(L);
lua.pushinteger(L, lua.Integer(plugin.Hook.BufferInput));
lua.setfield(L, -2, "OnBufferInput");
lua.pushinteger(L, lua.Integer(plugin.Hook.Draw));
lua.setfield(L, -2, "OnDraw");
lua.newtable(state.L);
lua.pushinteger(state.L, lua.Integer(plugin.Hook.BufferInput));
lua.setfield(state.L, -2, "OnBufferInput");
lua.pushinteger(state.L, lua.Integer(plugin.Hook.Draw));
lua.setfield(state.L, -2, "OnDraw");
}
lua.setfield(L, -2, "Hook");
lua.setfield(state.L, -2, "Hook");
lua.L_setfuncs(L, bbb, 0);
lua.setglobal(L, "Editor");
lua.L_setfuncs(state.L, bbb, 0);
lua.setglobal(state.L, "Editor");
lua.newtable(L);
lua.newtable(state.L);
{
lua.pushinteger(L, lua.Integer(ui.Axis.Horizontal));
lua.setfield(L, -2, "Horizontal");
lua.pushinteger(L, lua.Integer(ui.Axis.Vertical));
lua.setfield(L, -2, "Vertical");
push_lua_semantic_size_table(L, { ui.SemanticSizeKind.Fill, 0 });
lua.setfield(L, -2, "Fill");
push_lua_semantic_size_table(L, { ui.SemanticSizeKind.ChildrenSum, 0 });
lua.setfield(L, -2, "ChildrenSum");
push_lua_semantic_size_table(L, { ui.SemanticSizeKind.FitText, 0 });
lua.setfield(L, -2, "FitText");
lua.pushinteger(state.L, lua.Integer(ui.Axis.Horizontal));
lua.setfield(state.L, -2, "Horizontal");
lua.pushinteger(state.L, lua.Integer(ui.Axis.Vertical));
lua.setfield(state.L, -2, "Vertical");
push_lua_semantic_size_table(state.L, { ui.SemanticSizeKind.Fill, 0 });
lua.setfield(state.L, -2, "Fill");
push_lua_semantic_size_table(state.L, { ui.SemanticSizeKind.ChildrenSum, 0 });
lua.setfield(state.L, -2, "ChildrenSum");
push_lua_semantic_size_table(state.L, { ui.SemanticSizeKind.FitText, 0 });
lua.setfield(state.L, -2, "FitText");
lua.L_setfuncs(L, raw_data(&ui_lib), 0);
lua.setglobal(L, "UI");
lua.L_setfuncs(state.L, raw_data(&ui_lib), 0);
lua.setglobal(state.L, "UI");
}
if lua.L_dofile(L, "plugins/lua/view.lua") == i32(lua.OK) {
lua.pop(L, lua.gettop(L));
if lua.L_dofile(state.L, "plugins/lua/view.lua") == i32(lua.OK) {
lua.pop(state.L, lua.gettop(state.L));
} else {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error(err);
}
// Initialize Lua Plugins
{
lua.getglobal(L, "OnInit");
if lua.pcall(L, 0, 0, 0) == i32(lua.OK) {
lua.pop(L, lua.gettop(L));
lua.getglobal(state.L, "OnInit");
if lua.pcall(state.L, 0, 0, 0) == i32(lua.OK) {
lua.pop(state.L, lua.gettop(state.L));
} else {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error("failed to initialize plugin (OnInit):", err);
}
@ -1989,16 +2014,18 @@ main :: proc() {
// }
for hook_ref in state.lua_hooks[plugin.Hook.Draw] {
if draw_hooks, ok := state.lua_hooks[plugin.Hook.Draw]; ok {
for hook_ref in draw_hooks {
lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(hook_ref));
lua.pushlightuserdata(state.L, &ui_context);
if lua.pcall(state.L, 1, 0, 0) != i32(lua.OK) {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error(err);
} else {
lua.pop(L, lua.gettop(L));
lua.pop(state.L, lua.gettop(state.L));
}
}
}
@ -2053,12 +2080,12 @@ main :: proc() {
case core.LuaEditorAction:
lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(value.fn_ref));
if lua.pcall(state.L, 0, 0, 0) != i32(lua.OK) {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error(err);
} else {
lua.pop(L, lua.gettop(L));
lua.pop(state.L, lua.gettop(state.L));
}
if value.maybe_input_map.ctrl_key_actions != nil {
@ -2078,12 +2105,12 @@ main :: proc() {
case core.LuaEditorAction:
lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(value.fn_ref));
if lua.pcall(state.L, 0, 0, 0) != i32(lua.OK) {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error(err);
} else {
lua.pop(L, lua.gettop(L));
lua.pop(state.L, lua.gettop(state.L));
}
if value.maybe_input_map.key_actions != nil {
@ -2138,12 +2165,12 @@ main :: proc() {
for hook_ref in state.lua_hooks[plugin.Hook.BufferInput] {
lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(hook_ref));
if lua.pcall(state.L, 0, 0, 0) != i32(lua.OK) {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error(err);
} else {
lua.pop(L, lua.gettop(L));
lua.pop(state.L, lua.gettop(state.L));
}
}
}
@ -2168,12 +2195,12 @@ main :: proc() {
for hook_ref in state.lua_hooks[plugin.Hook.BufferInput] {
lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(hook_ref));
if lua.pcall(state.L, 0, 0, 0) != i32(lua.OK) {
err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L));
err := lua.tostring(state.L, lua.gettop(state.L));
lua.pop(state.L, lua.gettop(state.L));
log.error(err);
} else {
lua.pop(L, lua.gettop(L));
lua.pop(state.L, lua.gettop(state.L));
}
}
}
@ -2227,7 +2254,7 @@ main :: proc() {
plugin.on_exit();
}
}
lua.close(L);
lua.close(state.L);
sdl2.Quit();
}

View File

@ -1,6 +1,6 @@
package plugin;
import "core:intrinsics"
import "base:intrinsics"
import "core:dynlib"
import "core:fmt"
import "core:log"