132 lines
3.7 KiB
Zig
132 lines
3.7 KiB
Zig
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.TopBar");
|
|
|
|
allocator: std.mem.Allocator,
|
|
arena: std.heap.ArenaAllocator,
|
|
windowsMenu: std.ArrayListUnmanaged(*MenuEntry) = .{},
|
|
entriesByName: std.AutoHashMapUnmanaged(u32, *MenuEntry) = .{},
|
|
menuOpen: bool = false,
|
|
|
|
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
|
if (!first)
|
|
return;
|
|
|
|
self.* = .{
|
|
.allocator = allocator,
|
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
|
};
|
|
|
|
try self.addWindowsMenu(.{
|
|
.name = "sample window",
|
|
.vtable = &NeonObjectTable,
|
|
.open = false,
|
|
.ctx = self,
|
|
.windowFunction = windowOpen,
|
|
});
|
|
}
|
|
|
|
pub fn setEntryOpen(self: *@This(), name: []const u8, open: ?bool) void {
|
|
var n = core.MakeName(name);
|
|
const x = self.entriesByName.get(n.handle()).?;
|
|
if (open) |o| {
|
|
x.open = o;
|
|
} else {
|
|
x.open = !x.open;
|
|
}
|
|
}
|
|
|
|
pub fn addMenuObject(self: *@This(), ptr: anytype, comptime name: []const u8) !void {
|
|
const T = @TypeOf(ptr.*);
|
|
try self.addWindowsMenu(.{
|
|
.vtable = &T.NeonObjectTable,
|
|
.name = name,
|
|
.ctx = ptr,
|
|
.windowFunction = T.windowOpen,
|
|
});
|
|
}
|
|
|
|
pub fn windowOpen(entry: *MenuEntry, dt: f64) void {
|
|
_ = dt;
|
|
ig.showDemoWindow(&entry.open);
|
|
}
|
|
|
|
pub fn addWindowsMenu(self: *@This(), entry: MenuEntry) !void {
|
|
const new = try self.arena.allocator().create(MenuEntry);
|
|
new.* = entry;
|
|
var name = core.MakeName(entry.name);
|
|
|
|
if (self.entriesByName.getEntry(name.handle())) |e| {
|
|
core.logDisplay("TopBar", "{s} already registered, updating menu entry instead", .{entry.name});
|
|
e.value_ptr.*.* = entry;
|
|
} else {
|
|
try self.windowsMenu.append(self.arena.allocator(), new);
|
|
try self.entriesByName.put(self.arena.allocator(), name.handle(), new);
|
|
}
|
|
}
|
|
|
|
pub fn tick(self: *@This(), dt: f64) void {
|
|
if (!self.menuOpen) {
|
|
return;
|
|
}
|
|
|
|
if (ig.beginMainMenuBar()) {
|
|
if (ig.beginMenu("Windows..", true)) {
|
|
for (self.windowsMenu.items) |entry| {
|
|
if (ig.menuItem_Bool(entry.name.ptr, null, entry.open, true)) {
|
|
entry.open = !entry.open;
|
|
}
|
|
}
|
|
ig.endMenu();
|
|
}
|
|
|
|
if (ig.beginMenu("Operations", true)) {
|
|
if (ig.menuItem_Bool("Recompile", null, false, true)) {
|
|
core.engine_log("recompiling in DEBUG mode", .{});
|
|
|
|
var success = true;
|
|
_ = core.shell.runCmd(self.allocator, &.{ "zig", "build", "install" }, ".") catch {
|
|
core.graphics_logs("compile failed!");
|
|
success = false;
|
|
};
|
|
|
|
if (success)
|
|
core.graphics_logs("compile completed");
|
|
}
|
|
ig.endMenu();
|
|
}
|
|
|
|
ig.endMainMenuBar();
|
|
|
|
for (self.windowsMenu.items) |entry| {
|
|
if (entry.open) {
|
|
entry.updateFunc();
|
|
entry.windowFunction(entry, dt);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn destroy(self: *@This()) void {
|
|
self.arena.deinit();
|
|
}
|
|
|
|
pub const MenuEntry = struct {
|
|
name: []const u8,
|
|
open: bool = false,
|
|
ctx: ?*anyopaque,
|
|
windowFunction: *const fn (*MenuEntry, f64) void,
|
|
vtable: *core.EngineObjectVTable,
|
|
version: i32 = -1,
|
|
|
|
pub fn updateFunc(self: *@This()) void {
|
|
if (self.vtable.version != self.version) {
|
|
const func = self.vtable.findFunc("windowOpen");
|
|
self.windowFunction = @ptrCast(@alignCast(func));
|
|
self.version = self.vtable.version;
|
|
}
|
|
}
|
|
};
|
|
|
|
const ig = @import("../imgui.zig").api;
|
|
const std = @import("std");
|
|
const core = @import("core");
|