const ConsoleFunc = *const fn (args: []const u8) void; pub const ConsoleCommand = struct { func: ConsoleFunc, command: []u8, }; pub const Console = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console"); allocator: std.mem.Allocator = undefined, arena: std.heap.ArenaAllocator = undefined, commandMap: std.StringHashMapUnmanaged(ConsoleCommand) = .{}, pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { if (!first) { return; } self.* = .{ .arena = std.heap.ArenaAllocator.init(allocator), .allocator = allocator, }; core.engine_logs("console system created"); } pub fn addConsoleCommand(self: *@This(), funcName: []const u8, func: ConsoleFunc) !void { try self.commandMap.put(self.allocator, funcName, .{ .command = try self.arena.allocator().dupe(u8, funcName), .func = func, }); } pub fn eval(self: *@This(), c: []const u8) void { var i: usize = 0; const command = core.stringStrip(c); core.console_log("console_eval > {s}", .{c}); while (i < command.len) : (i += 1) { if (command[i] == ' ') { const func = command[0..i]; if (self.commandMap.get(func)) |entry| { entry.func(core.stringStrip(command[i..])); return; } core.console_log("unable to run console command: {s}", .{command}); return; } } // run the command solo if (self.commandMap.get(command)) |entry| { entry.func(""); } } pub fn deinit(self: *@This()) void { self.arena.deinit(); self.commandMap.deinit(self.allocator); } }; pub const getConsole = core.EngineObject(Console).get; pub fn start() !void { _ = try core.createObject(Console, .{}); } pub fn shutdown() void {} pub fn addCommand(funcName: []const u8, func: ConsoleFunc) !void { try getConsole().addConsoleCommand(funcName, func); } pub fn evaluate(cmd: []const u8) void { getConsole().eval(cmd); } const core = @import("core.zig"); const std = @import("std");