diff --git a/engine/core/src/console.zig b/engine/core/src/console.zig new file mode 100644 index 0000000..30845fa --- /dev/null +++ b/engine/core/src/console.zig @@ -0,0 +1,81 @@ +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()); + + allocator: std.mem.Allocator, + stringArena: std.heap.ArenaAllocator, + + commandMap: std.StringHashMapUnmanaged(ConsoleCommand) = .{}, + + pub fn create(allocator: std.mem.Allocator) !*@This() { + const self = try allocator.create(@This()); + self.* = .{ + .stringArena = std.heap.ArenaAllocator.init(allocator), + .allocator = allocator, + }; + + core.engine_logs("console system created"); + + return self; + } + + pub fn addConsoleCommand(self: *@This(), funcName: []const u8, func: ConsoleFunc) !void { + try self.commandMap.put(self.allocator, funcName, .{ + .command = try self.stringArena.allocator().dupe(u8, funcName), + .func = func, + }); + } + + pub fn eval(self: *@This(), c: []const u8) void { + var i: usize = 0; + const command = core.stringStrip(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 destroy(self: *@This()) void { + self.stringArena.deinit(); + self.commandMap.deinit(self.allocator); + self.allocator.destroy(self); + } +}; + +var gConsoleObject: *Console = undefined; + +pub fn start() !void { + gConsoleObject = try core.createObject(Console, .{}); +} + +pub fn shutdown() void {} + +pub fn addCommand(funcName: []const u8, func: ConsoleFunc) !void { + try gConsoleObject.addConsoleCommand(funcName, func); +} + +pub fn evaluate(cmd: []const u8) void { + gConsoleObject.eval(cmd); +} + +const core = @import("core.zig"); +const std = @import("std"); diff --git a/engine/core/src/core.zig b/engine/core/src/core.zig index bc1c73f..5fea533 100644 --- a/engine/core/src/core.zig +++ b/engine/core/src/core.zig @@ -131,6 +131,8 @@ pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std gEngine = try allocator.create(Engine); gEngine.* = try Engine.init(allocator); + try console.start(); + try configVars.setupConfigs(name ++ "Engine.ini"); if (@hasField(@TypeOf(args), "unitTest") and args.unitTest) {} else { @@ -163,6 +165,7 @@ pub fn shutdown_module(_: std.mem.Allocator) void { // LUA BEGIN script.shutdown_lua(); // LUA END + console.shutdown(); algorithm.string_pool.shutdown(); return; } @@ -236,6 +239,8 @@ pub const modules = @import("modules.zig"); pub const isModuleEnabled = modules.isModuleEnabled; pub const ModuleDescription = modules.ModuleDescription; +pub const console = @import("console.zig"); + pub const configVars = @import("configVars.zig"); pub const getConfigVar = configVars.getConfigVar; diff --git a/engine/core/src/logging.zig b/engine/core/src/logging.zig index 260785f..5395d95 100644 --- a/engine/core/src/logging.zig +++ b/engine/core/src/logging.zig @@ -59,6 +59,14 @@ pub fn ui_logs(comptime fmt: []const u8) void { printInner("[UI ]: " ++ fmt ++ "\n", .{}); } +pub fn console_log(comptime fmt: []const u8, args: anytype) void { + printInner("[CONSOLE ]: " ++ fmt ++ "\n", args); +} + +pub fn console_logs(comptime fmt: []const u8) void { + printInner("[CONSOLE ]: " ++ fmt ++ "\n"); +} + pub fn engine_log(comptime fmt: []const u8, args: anytype) void { printInner("[ENGINE ]: " ++ fmt ++ "\n", args); } diff --git a/engine/core/tests/tests.zig b/engine/core/tests/tests.zig index 4d77e18..ee3adbd 100644 --- a/engine/core/tests/tests.zig +++ b/engine/core/tests/tests.zig @@ -20,7 +20,9 @@ test "simple systems setup for core" { engine_logs("systems started, shutting down"); memory.MTPrintStatsDelta(); + try test_loadingConfigs(); + try test_consoleCommands(); try memory.dumpTimeline("test-core-timeline.txt"); } @@ -46,3 +48,21 @@ fn test_loadingConfigs() !void { core.engine_log("config string: {s}", .{height}); } } + +fn test_consoleCommands() !void { + const ConsoleCommands = struct { + pub fn echo(args: []const u8) void { + core.engine_log("{s}", .{args}); + } + + pub fn foo(args: []const u8) void { + core.engine_log("foo function called with args {s}", .{args}); + } + }; + + try core.console.addCommand("echo", ConsoleCommands.echo); + try core.console.addCommand("foo", ConsoleCommands.foo); + + core.console.evaluate("echo lmfao"); + core.console.evaluate("foo lmfao"); +} diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index 11348d6..ebed3b0 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -68,14 +68,6 @@ pub const Renderer = struct { // transients DO NOT TOUCH swapchainTexture: ?*gpu.GPUTexture = undefined, - // skyboxMesh: ?rend.IndexedMesh = null, - // skyboxTexture: ?*rend.Texture = null, - // skyboxTextureName: ?core.Name = null, - // skyboxPipeline: *gpu.GPUGraphicsPipeline = undefined, - // skyboxColor: core.colors.Color = .{ .r = 71.0 / 256.0, .g = 200.0 / 256.0, .b = 1.0, .a = 1.0 }, - - // skyboxMeshName: core.Name = core.DefineName("m_skybox"), - pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); pub const MaxObjectCount = 50000; @@ -148,50 +140,6 @@ pub const Renderer = struct { try self.createShadowCastingPipeline(); } - // pub fn setupSkybox(self: *@This()) !void { - // try assets.load( - // assets.MakeImportRefOptions( - // "Mesh", - // "m_skybox", - // .{ .path = "meshes/skybox.obj" }, - // ), - // ); - - // try self.createSkyboxPipeline(); - // } - - // pub fn createSkyboxPipeline(self: *@This()) !void { - // const vertex = try self.loadShader("skybox.vert", skybox_vert.LoadArgs); - // const fragment = try self.loadShader("skybox.frag", skybox_frag.LoadArgs); - - // var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); - // pci.vertex_shader = vertex; - // pci.fragment_shader = fragment; - - // var attributes = try self.generateVertexAttributeList(); - // defer attributes.deinit(); - - // pci.vertex_input_state = .{ - // .num_vertex_buffers = 1, - // .vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{ - // .{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 }, - // }, - // .num_vertex_attributes = @intCast(attributes.items.len), - // .vertex_attributes = @ptrCast(attributes.items.ptr), - // }; - - // pci.target_info.num_color_targets = 1; - // pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ - // .{ - // .format = self.device.getGPUSwapchainTextureFormat(self.window), - // .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), - // }, - // }; - - // pci.rasterizer_state.fill_mode = .fillmodeFill; - // self.skyboxPipeline = self.device.createGPUGraphicsPipeline(&pci); - // } - pub fn createSamplers(self: *@This()) !void { core.engine_log("creating blocky sampler", .{}); self.blockySampler = self.device.createGPUSampler(&std.mem.zeroInit(gpu.GPUSamplerCreateInfo, .{ @@ -652,37 +600,6 @@ pub const Renderer = struct { self.skyboxSystem.render(cmd); } - // render the skybox - // { - // if (self.skyboxMesh == null) { - // self.skyboxMesh = getMeshByName(&self.skyboxMeshName); - // } - // if (self.skyboxTexture == null) { - // if (self.skyboxTextureName) |*name| { - // self.skyboxTexture = getTexture(name); - // } - // } - // - // if (self.skyboxTexture) |skyboxTexture| { - // if (self.skyboxMesh) |skyboxMesh| { - // const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{ - // .texture = self.swapchainTexture.?, - // .clear_color = self.skyboxColor, - // .load_op = .loadopClear, - // .store_op = .storeopStore, - // }); - // - // const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, null); - // - // self.uploadSkyboxUniforms(cmd); - // renderpass.bindGPUGraphicsPipeline(self.skyboxPipeline); - // renderpass.bindGPUFragmentSamplers(0, &.{ .texture = skyboxTexture.texture, .sampler = self.blockySampler }, 1); - // renderpass.drawGPUIndexedPrimitives(skyboxMesh.index.size, 1, skyboxMesh.index.start, @intCast(skyboxMesh.vertex.start), 0); - // renderpass.endGPURenderPass(); - // } - // } - // } - // can cache this const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{ .texture = self.swapchainTexture.?, diff --git a/lib/p2/src/p2.zig b/lib/p2/src/p2.zig index dcee56e..119069d 100644 --- a/lib/p2/src/p2.zig +++ b/lib/p2/src/p2.zig @@ -10,6 +10,7 @@ pub const BumpArena = @import("structures/bump-arena.zig").BumpArena; pub const dupeString = utils.dupeString; pub const xxd = @import("utils/xxd.zig"); +pub const stringStrip = utils.stringStrip; pub const xxdWrite = xxd.xxdWrite; pub const loadFileAlloc = utils.loadFileAlloc; diff --git a/lib/p2/src/structures/string-pool.zig b/lib/p2/src/structures/string-pool.zig index dad774b..3eafda8 100644 --- a/lib/p2/src/structures/string-pool.zig +++ b/lib/p2/src/structures/string-pool.zig @@ -13,6 +13,9 @@ const std = @import("std"); // - substring() // - split() // - fmt() +// +// main purpose of this string-pool is to provide an RC-ableinterface for interface +// with GC'ed systems such as lua var gStringContext: *StringContext = undefined; diff --git a/lib/p2/src/structures/utils.zig b/lib/p2/src/structures/utils.zig index 43f691e..6a753ec 100644 --- a/lib/p2/src/structures/utils.zig +++ b/lib/p2/src/structures/utils.zig @@ -149,3 +149,21 @@ pub fn getFileExtension(path: []const u8) []const u8 { } return path; } + +// removes whitespace from start and end +pub fn stringStrip(p: []const u8) []const u8 { + var s: usize = 0; + while (s < p.len) : (s += 1) { + if (!std.ascii.isWhitespace(p[s])) { + break; + } + } + var e: usize = p.len; + while (e > 0) : (e -= 1) { + if (!std.ascii.isWhitespace(p[e - 1])) { + break; + } + } + + return p[s..e]; +}