added topbar, and a boatload of modules among other things - ecs container pointers are now updated across dll boundaries
This commit is contained in:
parent
cddf5b0cc2
commit
fefbc7436b
|
|
@ -139,6 +139,11 @@ pub fn getSessionStamp() i64 {
|
||||||
return gEngine.sessionStamp;
|
return gEngine.sessionStamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a struct can be used like a list of types in this way
|
||||||
|
pub const ComponentList = struct {
|
||||||
|
pub const Scene = scene.Scene;
|
||||||
|
};
|
||||||
|
|
||||||
pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||||
staticsInitialized = true;
|
staticsInitialized = true;
|
||||||
|
|
||||||
|
|
@ -190,9 +195,11 @@ pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allo
|
||||||
try algorithm.string_pool.setup(allocator);
|
try algorithm.string_pool.setup(allocator);
|
||||||
|
|
||||||
_ = try gEngine.createObject(script_bindings.ScriptTicks, .{ .can_tick = true });
|
_ = try gEngine.createObject(script_bindings.ScriptTicks, .{ .can_tick = true });
|
||||||
|
|
||||||
_ = try inputs.initInputStack();
|
_ = try inputs.initInputStack();
|
||||||
|
|
||||||
|
// components define
|
||||||
|
try ecs.defineComponentList(ComponentList, allocator);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,11 +210,19 @@ pub fn setupFromModule(__args: ModuleLoaderArgs) !void {
|
||||||
algorithm.names.gRegistry = __args.nameRegistry;
|
algorithm.names.gRegistry = __args.nameRegistry;
|
||||||
logging.setupLoggingFromModule();
|
logging.setupLoggingFromModule();
|
||||||
staticsInitialized = true;
|
staticsInitialized = true;
|
||||||
|
|
||||||
|
// walk through and patch all ecs containers
|
||||||
|
ecs.patchComponentList(ComponentList);
|
||||||
|
|
||||||
|
if (getEngineObject(SceneSystem)) |system| {
|
||||||
|
scene.Scene.SceneObjectContainer = system.sceneObjectContainer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown_module(_: std.mem.Allocator) void {
|
pub fn shutdown_module(_: std.mem.Allocator) void {
|
||||||
MemoryTracker.MTPrintStatsDelta();
|
MemoryTracker.MTPrintStatsDelta();
|
||||||
|
|
||||||
|
ecs.undefineComponentList(ComponentList);
|
||||||
logging.shutdownLogging();
|
logging.shutdownLogging();
|
||||||
debug_draw.shutdownDrawInterface();
|
debug_draw.shutdownDrawInterface();
|
||||||
|
|
||||||
|
|
@ -368,3 +383,31 @@ pub fn modulePreamble(p_allocator: *anyopaque, p_a: ?*anyopaque) !std.mem.Alloca
|
||||||
try setupFromModule(args);
|
try setupFromModule(args);
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a wrapper around a struct
|
||||||
|
// which adds slack up to a specific size
|
||||||
|
//
|
||||||
|
// engine objects must be allocated with this if they support hot patching
|
||||||
|
//
|
||||||
|
// if pub const Slack is a decl in the struct- EngineObjectVTable will generate with a
|
||||||
|
// fields remapping list.
|
||||||
|
|
||||||
|
pub fn SlackStruct(comptime T: type, comptime SlackSize: usize) type {
|
||||||
|
return struct {
|
||||||
|
inner: T,
|
||||||
|
slack: [SlackSize - @sizeOf(T)]u8 = undefined,
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*T {
|
||||||
|
return (try allocator.create(@This())).getInner();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getInner(self: *@This()) *T {
|
||||||
|
return &self.inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fromPtr(inner: *T) *@This() {
|
||||||
|
const p: *anyopaque = inner;
|
||||||
|
return @as(*@This(), @ptrCast(@alignCast(p)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,10 @@ pub const EcsRegistry = struct {
|
||||||
var containerName = _containerName;
|
var containerName = _containerName;
|
||||||
const newid = self.containers.items.len;
|
const newid = self.containers.items.len;
|
||||||
|
|
||||||
|
if (self.containersByName.contains(containerName.handle())) {
|
||||||
|
try core.assertf(false, "container already exists??", .{});
|
||||||
|
}
|
||||||
|
|
||||||
try self.containers.append(self.allocator, ref);
|
try self.containers.append(self.allocator, ref);
|
||||||
try self.containerNames.append(self.allocator, containerName);
|
try self.containerNames.append(self.allocator, containerName);
|
||||||
try self.containersByName.put(self.allocator, containerName.handle(), @intCast(newid));
|
try self.containersByName.put(self.allocator, containerName.handle(), @intCast(newid));
|
||||||
|
|
@ -283,13 +287,47 @@ pub const EcsRegistry = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn defineComponentList(comptime ComponentList: type, allocator: std.mem.Allocator) !void {
|
||||||
|
const typeInfo = @typeInfo(ComponentList).@"struct";
|
||||||
|
|
||||||
|
inline for (typeInfo.decls) |decl| {
|
||||||
|
core.engine_logs("defining component" ++ decl.name);
|
||||||
|
try defineComponent(@field(ComponentList, decl.name), allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn undefineComponentList(comptime ComponentList: type) void {
|
||||||
|
const typeInfo = @typeInfo(ComponentList).@"struct";
|
||||||
|
inline for (typeInfo.decls) |decl| {
|
||||||
|
undefineComponent(@field(ComponentList, decl.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this doesn't do any behaviour patching right now,
|
||||||
|
// only BaseContainer pointers
|
||||||
|
pub fn patchComponentList(comptime ComponentList: type) void {
|
||||||
|
const typeInfo = @typeInfo(ComponentList).@"struct";
|
||||||
|
if (core.getEngineObject(EcsRegistry)) |registry| {
|
||||||
|
inline for (typeInfo.decls) |decl| {
|
||||||
|
const T = @field(ComponentList, decl.name);
|
||||||
|
var name = core.MakeName(T.ComponentName);
|
||||||
|
|
||||||
|
if (registry.containersByName.get(name.handle())) |offset| {
|
||||||
|
core.engine_log("Patching component {s}", .{name.utf8()});
|
||||||
|
const ref = registry.containers.items[offset];
|
||||||
|
T.BaseContainer = @ptrCast(@alignCast(ref.ptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn defineComponent(comptime Component: type, allocator: std.mem.Allocator) !void {
|
pub fn defineComponent(comptime Component: type, allocator: std.mem.Allocator) !void {
|
||||||
const ContainerType = @TypeOf(Component.BaseContainer.*);
|
const ContainerType = @TypeOf(Component.BaseContainer.*);
|
||||||
Component.BaseContainer = try ContainerType.create(allocator);
|
Component.BaseContainer = try ContainerType.create(allocator);
|
||||||
|
|
||||||
core.engine_log("Component container created " ++ @typeName(Component) ++ " @{x}", .{@intFromPtr(Component.BaseContainer)});
|
core.engine_log("Component container created " ++ @typeName(Component) ++ " @{x}", .{@intFromPtr(Component.BaseContainer)});
|
||||||
const container = makeEcsContainerRef(Component.BaseContainer);
|
const container = makeEcsContainerRef(Component.BaseContainer);
|
||||||
try registerEcsContainer(container, core.MakeName(@typeName(Component)));
|
try registerEcsContainer(container, core.MakeName(Component.ComponentName));
|
||||||
|
|
||||||
try script.registerComponent(Component, container);
|
try script.registerComponent(Component, container);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ pub const Engine = struct {
|
||||||
self.createObjectLock = true;
|
self.createObjectLock = true;
|
||||||
defer self.createObjectLock = false;
|
defer self.createObjectLock = false;
|
||||||
const newIndex = self.engineObjects.items.len;
|
const newIndex = self.engineObjects.items.len;
|
||||||
const newObjectPtr = try vtable.init_func(self.allocator);
|
const newObjectPtr = try vtable.init_func(self.allocator); // call this thing with the special allocator that adds vtable. slackSize to it.
|
||||||
|
|
||||||
const newObjectRef = EngineObjectRef{
|
const newObjectRef = EngineObjectRef{
|
||||||
.ptr = @as(*anyopaque, @ptrCast(newObjectPtr)),
|
.ptr = @as(*anyopaque, @ptrCast(newObjectPtr)),
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,45 @@ pub const EngineDataEventError = error{
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const FieldInfo = struct {
|
||||||
|
name: []const u8,
|
||||||
|
size: u32,
|
||||||
|
offset: u32,
|
||||||
|
alignment: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn PatchStruct(comptime T: type, p: *T, old: []const FieldInfo) void {
|
||||||
|
const t = @typeInfo(T).@"struct";
|
||||||
|
|
||||||
|
var new: T = .{};
|
||||||
|
|
||||||
|
inline for (t.fields) |field| {
|
||||||
|
var oldField: ?FieldInfo = null;
|
||||||
|
|
||||||
|
for (old) |oldFieldSearch| {
|
||||||
|
if (std.mem.eql(u8, field.name, oldFieldSearch.name)) {
|
||||||
|
oldField = oldFieldSearch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldField) |of| {
|
||||||
|
var src: []const u8 = undefined;
|
||||||
|
src.ptr = @ptrCast(p);
|
||||||
|
src.ptr += of.offset;
|
||||||
|
src.len = @sizeOf(@TypeOf(@field(p, field.name)));
|
||||||
|
|
||||||
|
var dest: []u8 = undefined;
|
||||||
|
dest.ptr = @ptrCast(&@field(new, field.name));
|
||||||
|
dest.len = @sizeOf(@TypeOf(@field(new, field.name)));
|
||||||
|
|
||||||
|
std.mem.copyForwards(u8, dest, src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.* = new;
|
||||||
|
}
|
||||||
|
|
||||||
pub const EngineObjectVTable = struct {
|
pub const EngineObjectVTable = struct {
|
||||||
typeName: []const u8,
|
typeName: []const u8,
|
||||||
typeSize: usize,
|
typeSize: usize,
|
||||||
|
|
@ -60,6 +99,37 @@ pub const EngineObjectVTable = struct {
|
||||||
readyToExit_func: ?*const fn (*anyopaque) bool = null,
|
readyToExit_func: ?*const fn (*anyopaque) bool = null,
|
||||||
|
|
||||||
prepare_func: ?*const fn (*anyopaque) EngineDataEventError!void = null,
|
prepare_func: ?*const fn (*anyopaque) EngineDataEventError!void = null,
|
||||||
|
fieldListHash: ?usize = null,
|
||||||
|
fieldList: ?[]const FieldInfo = null,
|
||||||
|
slackSize: ?usize = null,
|
||||||
|
|
||||||
|
fn fieldInfoCompare(_: void, a: FieldInfo, b: FieldInfo) bool {
|
||||||
|
return a.offset < b.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addFieldList(self: *@This(), comptime TargetType: type) void {
|
||||||
|
if (!@hasDecl(TargetType, "Slack")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.slackSize = @sizeOf(TargetType.Slack);
|
||||||
|
const typeinfo = @typeInfo(TargetType).@"struct";
|
||||||
|
const fieldList = blk: {
|
||||||
|
comptime var f: []const FieldInfo = &.{};
|
||||||
|
inline for (typeinfo.fields) |field| {
|
||||||
|
f = f ++ .{FieldInfo{
|
||||||
|
.name = field.name,
|
||||||
|
.offset = @intCast(@offsetOf(TargetType, field.name)),
|
||||||
|
.size = @intCast(@sizeOf(field.type)),
|
||||||
|
.alignment = @alignOf(field.type),
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
break :blk f;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.fieldList = fieldList;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from(comptime TargetType: type, comptime engineObjectName: ?[]const u8) EngineObjectVTable {
|
pub fn from(comptime TargetType: type, comptime engineObjectName: ?[]const u8) EngineObjectVTable {
|
||||||
var self = EngineObjectVTable{
|
var self = EngineObjectVTable{
|
||||||
|
|
@ -68,6 +138,7 @@ pub const EngineObjectVTable = struct {
|
||||||
.typeAlign = @alignOf(TargetType),
|
.typeAlign = @alignOf(TargetType),
|
||||||
.init_func = undefined,
|
.init_func = undefined,
|
||||||
};
|
};
|
||||||
|
self.addFieldList(TargetType);
|
||||||
|
|
||||||
if (engineObjectName) |eon| {
|
if (engineObjectName) |eon| {
|
||||||
self.singletonName = eon;
|
self.singletonName = eon;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ pub const LoadedModule = struct {
|
||||||
lastLoad: i64 = 0,
|
lastLoad: i64 = 0,
|
||||||
lastModification: i64 = 0,
|
lastModification: i64 = 0,
|
||||||
|
|
||||||
|
pdbPath: ?[]const u8 = null,
|
||||||
|
|
||||||
startOnLoad: bool = true,
|
startOnLoad: bool = true,
|
||||||
started: bool = false,
|
started: bool = false,
|
||||||
initialLoad: bool = true,
|
initialLoad: bool = true,
|
||||||
|
|
@ -51,6 +53,11 @@ pub const LoadedModule = struct {
|
||||||
|
|
||||||
try std.fs.cwd().copyFile(self.baseModulePath, std.fs.cwd(), stagedPath, .{});
|
try std.fs.cwd().copyFile(self.baseModulePath, std.fs.cwd(), stagedPath, .{});
|
||||||
|
|
||||||
|
if (self.pdbPath) |pdbPath| {
|
||||||
|
const stagedPdbPath = try std.fmt.allocPrint(allocator, "{s}/{s}.pdb", .{ stagingDirectoryPath, self.moduleName });
|
||||||
|
try std.fs.cwd().copyFile(pdbPath, std.fs.cwd(), stagedPdbPath, .{});
|
||||||
|
}
|
||||||
|
|
||||||
self.stagedPaths.append(allocator, stagedPath) catch unreachable;
|
self.stagedPaths.append(allocator, stagedPath) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,6 +146,10 @@ pub const ModuleLoader = struct {
|
||||||
.lastModification = std.time.microTimestamp(),
|
.lastModification = std.time.microTimestamp(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (@import("builtin").os.tag == .windows) {
|
||||||
|
loaded.pdbPath = try std.fmt.allocPrint(self.arena.allocator(), "zig-out/modules/{s}.pdb", .{libFileName[0 .. libFileName.len - 4]});
|
||||||
|
}
|
||||||
|
|
||||||
try core.fs().addFileChangedCallback(libFileName, dllChangedCallback, loaded);
|
try core.fs().addFileChangedCallback(libFileName, dllChangedCallback, loaded);
|
||||||
|
|
||||||
try self.loadedModules.append(self.arena.allocator(), loaded);
|
try self.loadedModules.append(self.arena.allocator(), loaded);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,31 @@ const LogBufferSize = 1 * 1024 * 1024; // 1Mb buffer log
|
||||||
|
|
||||||
var gLoggerSys: ?*LoggerSys = null;
|
var gLoggerSys: ?*LoggerSys = null;
|
||||||
|
|
||||||
|
pub const LogBuffer = struct {
|
||||||
|
lock: std.Thread.Mutex = .{},
|
||||||
|
buffer: std.ArrayList(u8),
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator) @This() {
|
||||||
|
return .{
|
||||||
|
.buffer = std.ArrayList(u8).init(allocator),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lockWriter(self: *@This()) std.ArrayList(u8).Writer {
|
||||||
|
self.lock.lock();
|
||||||
|
return self.buffer.writer();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unlock(self: *@This()) void {
|
||||||
|
self.lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *@This()) void {
|
||||||
|
self.lock.lock();
|
||||||
|
self.buffer.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub fn printRaw(comptime fmt: []const u8, args: anytype) void {
|
pub fn printRaw(comptime fmt: []const u8, args: anytype) void {
|
||||||
if (zero_logging) {
|
if (zero_logging) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -42,9 +67,13 @@ pub fn printInner(comptime fmt: []const u8, args: anytype) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new logging API
|
||||||
|
pub fn logDisplay(comptime prefix: []const u8, comptime fmt: []const u8, args: anytype) void {
|
||||||
|
printInner("[" ++ prefix ++ "]: " ++ fmt ++ "\n", args);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn game_log(comptime fmt: []const u8, args: anytype) void {
|
pub fn game_log(comptime fmt: []const u8, args: anytype) void {
|
||||||
printInner("[GAME ]: " ++ fmt ++ "\n", args);
|
printInner("[GAME ]: " ++ fmt ++ "\n", args);
|
||||||
printInner("[SCRIPT ]: " ++ fmt ++ "\n", args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn game_logs(comptime fmt: []const u8) void {
|
pub fn game_logs(comptime fmt: []const u8) void {
|
||||||
|
|
@ -168,6 +197,8 @@ pub const LoggerSys = struct {
|
||||||
lock: std.Thread.Mutex = .{},
|
lock: std.Thread.Mutex = .{},
|
||||||
flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||||
|
|
||||||
|
sessionBuffer: ?*LogBuffer = null, // disabled in release modes
|
||||||
|
|
||||||
pub fn flush(self: *@This()) !void {
|
pub fn flush(self: *@This()) !void {
|
||||||
var z = tracy.ZoneN(@src(), "Trying to flush");
|
var z = tracy.ZoneN(@src(), "Trying to flush");
|
||||||
defer z.End();
|
defer z.End();
|
||||||
|
|
@ -235,6 +266,11 @@ pub const LoggerSys = struct {
|
||||||
pub fn print(self: *@This(), comptime fmt: []const u8, args: anytype) !void {
|
pub fn print(self: *@This(), comptime fmt: []const u8, args: anytype) !void {
|
||||||
self.lock.lock();
|
self.lock.lock();
|
||||||
try self.writeOutBuffer.writer().print(fmt, args);
|
try self.writeOutBuffer.writer().print(fmt, args);
|
||||||
|
if (self.sessionBuffer != null) {
|
||||||
|
try self.sessionBuffer.?.lockWriter().print(fmt, args);
|
||||||
|
self.sessionBuffer.?.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
self.lock.unlock();
|
self.lock.unlock();
|
||||||
|
|
||||||
if (self.writeOutBuffer.items.len > LogBufferSize) {
|
if (self.writeOutBuffer.items.len > LogBufferSize) {
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ pub const SceneSystem = struct {
|
||||||
dynamicObjects: ArrayListUnmanaged(core.ObjectHandle) = .{},
|
dynamicObjects: ArrayListUnmanaged(core.ObjectHandle) = .{},
|
||||||
childrenArena: std.heap.ArenaAllocator,
|
childrenArena: std.heap.ArenaAllocator,
|
||||||
tickCount: u32 = 0,
|
tickCount: u32 = 0,
|
||||||
|
sceneObjectContainer: *SceneObjectSet = undefined,
|
||||||
|
|
||||||
pub const Field = SceneObjectSet.Field;
|
pub const Field = SceneObjectSet.Field;
|
||||||
pub const FieldType = SceneObjectSet.FieldType;
|
pub const FieldType = SceneObjectSet.FieldType;
|
||||||
|
|
@ -365,8 +366,10 @@ pub const SceneSystem = struct {
|
||||||
.childrenArena = std.heap.ArenaAllocator.init(allocator),
|
.childrenArena = std.heap.ArenaAllocator.init(allocator),
|
||||||
};
|
};
|
||||||
core.EngineObject(@This()).gInstance = self;
|
core.EngineObject(@This()).gInstance = self;
|
||||||
try core.defineComponent(Scene, allocator);
|
// try core.defineComponent(Scene, allocator);
|
||||||
Scene.SceneObjectContainer = try SceneObjectSet.create(allocator);
|
Scene.SceneObjectContainer = try SceneObjectSet.create(allocator);
|
||||||
|
self.sceneObjectContainer = Scene.SceneObjectContainer;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,7 +391,7 @@ pub const SceneSystem = struct {
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
self.dynamicObjects.deinit(self.allocator);
|
self.dynamicObjects.deinit(self.allocator);
|
||||||
self.childrenArena.deinit();
|
self.childrenArena.deinit();
|
||||||
core.undefineComponent(Scene);
|
// core.undefineComponent(Scene);
|
||||||
Scene.SceneObjectContainer.destroy();
|
Scene.SceneObjectContainer.destroy();
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
||||||
|
|
||||||
const gimgui = try core.createObject(Impl, .{});
|
const gimgui = try core.createObject(Impl, .{});
|
||||||
try gimgui.setup();
|
try gimgui.setup();
|
||||||
|
|
||||||
|
_ = try core.createObject(utils.TopBar, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setupFromModule() void {
|
pub fn setupFromModule() void {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject");
|
||||||
|
pub const Slack = core.SlackStruct(@This(), 256);
|
||||||
|
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
arena: std.heap.ArenaAllocator,
|
||||||
|
windowsMenu: std.ArrayListUnmanaged(*MenuEntry) = .{},
|
||||||
|
entriesByName: std.AutoHashMapUnmanaged(u32, *MenuEntry) = .{},
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try Slack.create(allocator);
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
|
};
|
||||||
|
|
||||||
|
try self.addWindowsMenu(.{
|
||||||
|
.name = "sample window",
|
||||||
|
.open = false,
|
||||||
|
.ctx = self,
|
||||||
|
.windowFunction = windowOpen,
|
||||||
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn addMenuObject(self: *@This(), ptr: anytype, comptime name: []const u8) !void {
|
||||||
|
const T = @TypeOf(ptr.*);
|
||||||
|
try self.addWindowsMenu(.{
|
||||||
|
.name = name,
|
||||||
|
.ctx = ptr,
|
||||||
|
.windowFunction = T.windowOpen,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn windowOpen(entry: *MenuEntry, dt: f64) void {
|
||||||
|
_ = dt;
|
||||||
|
|
||||||
|
if (ig.begin("sample window", &entry.open, .{})) {}
|
||||||
|
ig.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
ig.showDemoWindow(null);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
ig.endMainMenuBar();
|
||||||
|
|
||||||
|
for (self.windowsMenu.items) |entry| {
|
||||||
|
if (entry.open) {
|
||||||
|
entry.windowFunction(entry, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.arena.deinit();
|
||||||
|
self.allocator.destroy(Slack.fromPtr(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const MenuEntry = struct {
|
||||||
|
name: []const u8,
|
||||||
|
open: bool = false,
|
||||||
|
ctx: ?*anyopaque,
|
||||||
|
windowFunction: *const fn (*MenuEntry, f64) void,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ig = @import("../imgui.zig").api;
|
||||||
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
buffer: core.LogBuffer,
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
lastLength: usize = 0,
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator) @This() {
|
||||||
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.buffer = core.LogBuffer.init(allocator),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setup(self: *@This()) void {
|
||||||
|
if (core.getLogger()) |logger| {
|
||||||
|
logger.sessionBuffer = &self.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getEngineObject(imgui.utils.TopBar)) |topBar| {
|
||||||
|
topBar.addMenuObject(self, "Console") catch {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn windowOpen(entry: *imgui.utils.MenuEntry, dt: f64) void {
|
||||||
|
_ = dt;
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(entry.ctx));
|
||||||
|
|
||||||
|
self.buffer.lock.lock();
|
||||||
|
defer self.buffer.lock.unlock();
|
||||||
|
|
||||||
|
if (ig.begin("Console Output", &entry.open, .{})) {
|
||||||
|
ig.textSlice(self.buffer.buffer.items);
|
||||||
|
if (self.lastLength != self.buffer.buffer.items.len)
|
||||||
|
ig.setScrollHereY(1.0);
|
||||||
|
}
|
||||||
|
ig.end();
|
||||||
|
|
||||||
|
self.lastLength = self.buffer.buffer.items.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *@This()) void {
|
||||||
|
self.buffer.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const imgui = @import("../imgui.zig");
|
||||||
|
const ig = imgui.api;
|
||||||
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
@ -79,5 +79,42 @@ pub inline fn displayStruct(s: anytype, comptime depth: u32, comptime maxDepth:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var staticText: [2048]u8 = undefined;
|
||||||
|
|
||||||
|
pub fn hexText(bytes: []const u8) void {
|
||||||
|
var stream = std.io.fixedBufferStream(&staticText);
|
||||||
|
var writer = stream.writer();
|
||||||
|
|
||||||
|
var b = bytes;
|
||||||
|
if (b.len > 2040)
|
||||||
|
b.len = 2040;
|
||||||
|
core.xxdWrite(writer, bytes, .{}) catch return;
|
||||||
|
|
||||||
|
const offset = writer.context.getPos() catch return;
|
||||||
|
const text = staticText[0..offset];
|
||||||
|
|
||||||
|
ig.textSlice(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn structHexView(ptr: anytype) void {
|
||||||
|
const T = @typeInfo(@TypeOf(ptr)).pointer.child;
|
||||||
|
|
||||||
|
if (ig.begin("struct debugger hexview: " ++ @typeName(T), null, .{})) {
|
||||||
|
const typeInfo = @typeInfo(T).@"struct";
|
||||||
|
if (@hasDecl(T, "Slack")) {
|
||||||
|
ig.textf("size: {d}/{d} bytes", .{ @sizeOf(T), @sizeOf(T.Slack) });
|
||||||
|
}
|
||||||
|
inline for (typeInfo.fields) |field| {
|
||||||
|
const offset = @offsetOf(T, field.name);
|
||||||
|
ig.textf("+{d}(0x{x}) size: {d}> {s} ", .{ offset, offset, @sizeOf(field.type), field.name });
|
||||||
|
hexText(&std.mem.toBytes(@field(ptr, field.name)));
|
||||||
|
ig.separator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ig.end();
|
||||||
|
}
|
||||||
|
|
||||||
const ig = @import("../imgui.zig").api;
|
const ig = @import("../imgui.zig").api;
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
|
||||||
|
|
@ -1 +1,15 @@
|
||||||
pub const structDebugWindow = @import("structDebugger.zig").structDebugWindow;
|
pub const structDebugger = @import("structDebugger.zig");
|
||||||
|
pub const structDebugWindow = structDebugger.structDebugWindow;
|
||||||
|
pub const structHexView = structDebugger.structHexView;
|
||||||
|
pub const ConsoleWindow = @import("consoleWindow.zig");
|
||||||
|
|
||||||
|
pub const TopBar = @import("TopBar.zig");
|
||||||
|
pub const MenuEntry = TopBar.MenuEntry;
|
||||||
|
|
||||||
|
pub fn addMenuFunc(ctx: ?*anyopaque, name: []const u8, func: *const fn (*MenuEntry, f64) void) void {
|
||||||
|
if (core.getEngineObject(TopBar)) |topbar| {
|
||||||
|
topbar.addWindowsMenu(.{ .name = name, .ctx = ctx, .windowFunction = func }) catch {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const core = @import("core");
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,11 @@ pub const PrimitiveType = enum {
|
||||||
sphere,
|
sphere,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const ComponentList = struct {
|
||||||
|
pub const _PhysicsCharacter = PhysicsCharacter;
|
||||||
|
pub const _PhysicsCollider = PhysicsCollider;
|
||||||
|
};
|
||||||
|
|
||||||
// low level helpers - old api
|
// low level helpers - old api
|
||||||
pub fn addPrimitiveBody(primitive: PrimitiveType, settings: BodyCreationSettings, activationMode: Activation) !BodyId {
|
pub fn addPrimitiveBody(primitive: PrimitiveType, settings: BodyCreationSettings, activationMode: Activation) !BodyId {
|
||||||
const interface = context().system.getBodyInterfaceMut();
|
const interface = context().system.getBodyInterfaceMut();
|
||||||
|
|
@ -78,11 +83,18 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
||||||
_ = args;
|
_ = args;
|
||||||
_ = spec;
|
_ = spec;
|
||||||
|
|
||||||
|
core.engine_logs("starting physics");
|
||||||
|
try core.defineComponentList(ComponentList, allocator);
|
||||||
try zphysics.init(allocator, .{});
|
try zphysics.init(allocator, .{});
|
||||||
_ = try core.createObject(runtime.PhysicsRuntime, .{ .can_tick = true });
|
_ = try core.createObject(runtime.PhysicsRuntime, .{ .can_tick = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setupFromModule() void {
|
||||||
|
core.ecs.patchComponentList(ComponentList);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
||||||
|
core.undefineComponentList(ComponentList);
|
||||||
_ = allocator;
|
_ = allocator;
|
||||||
zphysics.deinit();
|
zphysics.deinit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,8 +172,8 @@ pub const PhysicsRuntime = struct {
|
||||||
|
|
||||||
self.system = system;
|
self.system = system;
|
||||||
|
|
||||||
try core.defineComponent(PhysicsCharacter, self.allocator);
|
//try core.defineComponent(PhysicsCharacter, self.allocator);
|
||||||
try core.defineComponent(PhysicsCollider, self.allocator);
|
// try core.defineComponent(PhysicsCollider, self.allocator);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
@ -227,8 +227,8 @@ pub const PhysicsRuntime = struct {
|
||||||
physChar.deinit();
|
physChar.deinit();
|
||||||
}
|
}
|
||||||
self.idToEntity.deinit(self.allocator);
|
self.idToEntity.deinit(self.allocator);
|
||||||
core.undefineComponent(PhysicsCharacter);
|
// core.undefineComponent(PhysicsCharacter);
|
||||||
core.undefineComponent(PhysicsCollider);
|
// core.undefineComponent(PhysicsCollider);
|
||||||
self.shapes.deinit(self.allocator);
|
self.shapes.deinit(self.allocator);
|
||||||
self.system.destroy();
|
self.system.destroy();
|
||||||
allocator.destroy(self);
|
allocator.destroy(self);
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,25 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
||||||
rendAllocator = allocator;
|
rendAllocator = allocator;
|
||||||
try renderer.createInstance();
|
try renderer.createInstance();
|
||||||
try renderer.start();
|
try renderer.start();
|
||||||
|
|
||||||
|
try core.defineComponentList(ComponentList, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const ComponentList = struct {
|
||||||
|
pub const _MeshComponent = MeshComponent;
|
||||||
|
pub const _CameraComponent = CameraComponent;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn setupFromModule() void {
|
||||||
|
if (core.getEngineObject(renderer.Renderer)) |r| {
|
||||||
|
rendAllocator = r.allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.ecs.patchComponentList(ComponentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
||||||
core.undefineComponent(MeshComponent);
|
core.undefineComponentList(ComponentList);
|
||||||
core.undefineComponent(CameraComponent);
|
|
||||||
_ = allocator;
|
_ = allocator;
|
||||||
renderer.shutdown();
|
renderer.shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@ pub const MeshPool = struct {
|
||||||
pub fn create(device: *gpu.GPUDevice, allocator: std.mem.Allocator, settings: MeshPoolCreationSettings) !*@This() {
|
pub fn create(device: *gpu.GPUDevice, allocator: std.mem.Allocator, settings: MeshPoolCreationSettings) !*@This() {
|
||||||
const self = try allocator.create(@This());
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
gMeshPool = self;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.indexSpans = try core.MergedSpans.init(allocator, settings.indexCount),
|
.indexSpans = try core.MergedSpans.init(allocator, settings.indexCount),
|
||||||
|
|
@ -185,19 +183,17 @@ pub const MeshPool = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// === renderer interface implementation ===
|
/// === renderer interface implementation ===
|
||||||
var gMeshPool: *MeshPool = undefined;
|
|
||||||
|
|
||||||
pub fn getMesh(name: []const u8) ?rend.IndexedMesh {
|
pub fn getMesh(name: []const u8) ?rend.IndexedMesh {
|
||||||
var n = core.MakeName(name);
|
var n = core.MakeName(name);
|
||||||
return getMeshByName(&n);
|
return getMeshByName(&n);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMeshByName(name: *core.Name) ?rend.IndexedMesh {
|
pub fn getMeshByName(name: *core.Name) ?rend.IndexedMesh {
|
||||||
return gMeshPool.installedMeshes.get(name.handle());
|
return rend.context().meshPool.installedMeshes.get(name.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pushMeshUpdate(meshUpdate: rend.MeshUpdate) !void {
|
pub fn pushMeshUpdate(meshUpdate: rend.MeshUpdate) !void {
|
||||||
try gMeshPool.pushMeshUpdate(meshUpdate);
|
try rend.context().meshPool.pushMeshUpdate(meshUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MeshAssetLoader = @import("MeshAssetLoader.zig");
|
const MeshAssetLoader = @import("MeshAssetLoader.zig");
|
||||||
|
|
|
||||||
|
|
@ -96,9 +96,6 @@ pub const Renderer = struct {
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
try core.defineComponent(rend.MeshComponent, allocator);
|
|
||||||
try core.defineComponent(rend.CameraComponent, allocator);
|
|
||||||
|
|
||||||
self.hdrTextureFormat = .textureformatR16g16b16a16Float;
|
self.hdrTextureFormat = .textureformatR16g16b16a16Float;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
windowOpen: bool = true,
|
|
||||||
|
|
||||||
lastUpdateFrame: u64 = 0,
|
lastUpdateFrame: u64 = 0,
|
||||||
arena: std.heap.ArenaAllocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
@ -13,6 +12,10 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (core.getEngineObject(igutils.TopBar)) |topbar| {
|
||||||
|
topbar.addMenuObject(self, "Engine Object Browser") catch {};
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,19 +45,29 @@ pub fn maybeUpdate(self: *@This()) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *@This()) void {
|
pub fn windowOpen(entry: *igutils.MenuEntry, dt: f64) void {
|
||||||
if (self.windowOpen) {
|
_ = dt;
|
||||||
if (ig.begin("EngineTool", &self.windowOpen, .{})) {
|
const self: *@This() = @ptrCast(@alignCast(entry.ctx));
|
||||||
self.maybeUpdate() catch {
|
|
||||||
ig.textSlice("Unable to update engine tools list");
|
if (ig.begin("EngineTool", &entry.open, .{})) {
|
||||||
return;
|
self.maybeUpdate() catch {
|
||||||
};
|
ig.textSlice("Unable to update engine tools list");
|
||||||
for (self.strings.items) |slice| {
|
return;
|
||||||
ig.textSlice(slice);
|
};
|
||||||
|
for (self.strings.items) |slice| {
|
||||||
|
ig.textSlice(slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getEngineObject(core.EcsRegistry)) |ecsReg| {
|
||||||
|
ig.separator();
|
||||||
|
|
||||||
|
for (ecsReg.containerNames.items, 0..) |*name, i| {
|
||||||
|
_ = i;
|
||||||
|
ig.textf("{s}", .{name.utf8()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ig.end();
|
|
||||||
}
|
}
|
||||||
|
ig.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
|
|
@ -67,3 +80,4 @@ const backlog = @import("Backlog");
|
||||||
const core = backlog.core;
|
const core = backlog.core;
|
||||||
const rend = backlog.rend;
|
const rend = backlog.rend;
|
||||||
const ig = backlog.imgui.api;
|
const ig = backlog.imgui.api;
|
||||||
|
const igutils = backlog.imgui.utils;
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,28 @@
|
||||||
dtAverage: f64 = 0.0,
|
dtAverage: f64 = 0.0,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), null);
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "extras.RendererDebug");
|
||||||
|
|
||||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
const self = try allocator.create(@This());
|
const self = try allocator.create(@This());
|
||||||
|
|
||||||
self.* = .{ .allocator = allocator };
|
self.* = .{ .allocator = allocator };
|
||||||
|
|
||||||
|
self.setup();
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *@This(), dt: f64) void {
|
// setups are a non-failable functions that get reran after patchStruct() is called
|
||||||
|
pub fn setup(self: *@This()) void {
|
||||||
|
if (core.getEngineObject(igu.TopBar)) |topbar| {
|
||||||
|
topbar.addMenuObject(self, "Renderer Debug") catch {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn windowOpen(entry: *igu.MenuEntry, dt: f64) void {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(entry.ctx));
|
||||||
|
|
||||||
core.rollingAverage(&self.dtAverage, dt, 50);
|
core.rollingAverage(&self.dtAverage, dt, 50);
|
||||||
|
|
||||||
if (ig.begin("renderer debug", null, .{})) {
|
if (ig.begin("renderer debug", null, .{})) {
|
||||||
|
|
@ -43,4 +54,5 @@ const backlog = @import("Backlog");
|
||||||
const core = backlog.core;
|
const core = backlog.core;
|
||||||
const rend = backlog.rend;
|
const rend = backlog.rend;
|
||||||
const ig = backlog.imgui.api;
|
const ig = backlog.imgui.api;
|
||||||
|
const igu = backlog.imgui.utils;
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,13 @@ fn debugShowKeys(binding: anytype) void {
|
||||||
ig.textFmt("{s} ({s}) keysDown count: {d}", .{ binding.data.name.utf8(), @typeName(@TypeOf(binding)), binding.data.keysDown.count() }) catch return;
|
ig.textFmt("{s} ({s}) keysDown count: {d}", .{ binding.data.name.utf8(), @typeName(@TypeOf(binding)), binding.data.keysDown.count() }) catch return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick() void {
|
pub fn windowOpen(entry: *igutils.MenuEntry, dt: f64) void {
|
||||||
|
const self: *@This() = @ptrCast(@alignCast(entry.ctx));
|
||||||
|
_ = dt;
|
||||||
|
_ = self;
|
||||||
|
|
||||||
const stack = core.inputs.getInputStack();
|
const stack = core.inputs.getInputStack();
|
||||||
if (ig.begin("input stack", null, .{})) {
|
if (ig.begin("input stack", &entry.open, .{})) {
|
||||||
for (stack.active.bindingStack.items) |binding| {
|
for (stack.active.bindingStack.items) |binding| {
|
||||||
switch (binding) {
|
switch (binding) {
|
||||||
.action => |b| {
|
.action => |b| {
|
||||||
|
|
@ -33,3 +37,4 @@ const backlog = @import("Backlog");
|
||||||
const core = backlog.core;
|
const core = backlog.core;
|
||||||
const rend = backlog.rend;
|
const rend = backlog.rend;
|
||||||
const ig = backlog.imgui.api;
|
const ig = backlog.imgui.api;
|
||||||
|
const igutils = backlog.imgui.utils;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ pub const Options = struct {
|
||||||
absoluteSpawnposition: bool = false, // if set, won't move the object to where the spawn rotation and position is
|
absoluteSpawnposition: bool = false, // if set, won't move the object to where the spawn rotation and position is
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.objectSpawner");
|
||||||
|
|
||||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
const self = try allocator.create(@This());
|
const self = try allocator.create(@This());
|
||||||
self.* = .{
|
self.* = .{
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ pub fn build(b: *std.Build) void {
|
||||||
});
|
});
|
||||||
|
|
||||||
blbuild.addExtraModule(sampleGameExtern.root_module, "gameExtras");
|
blbuild.addExtraModule(sampleGameExtern.root_module, "gameExtras");
|
||||||
|
blbuild.addExtraModule(sampleGameExtern.root_module, "bsp");
|
||||||
sampleGameExtern.root_module.addImport("backlog", blbuild.nw_mod);
|
sampleGameExtern.root_module.addImport("backlog", blbuild.nw_mod);
|
||||||
|
|
||||||
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ pub export fn startup(p_allocator: *anyopaque, p_a: ?*anyopaque) bool {
|
||||||
_ = allocator;
|
_ = allocator;
|
||||||
imgui.setupFromModule();
|
imgui.setupFromModule();
|
||||||
platform.setupFromModule();
|
platform.setupFromModule();
|
||||||
|
rend.setupFromModule();
|
||||||
|
backlog.physics.setupFromModule();
|
||||||
// TODO backlog.setupFromModule
|
// TODO backlog.setupFromModule
|
||||||
|
|
||||||
start_module(core.startup_getArgs(p_a.?)) catch return false;
|
start_module(core.startup_getArgs(p_a.?)) catch return false;
|
||||||
|
|
@ -20,44 +22,96 @@ pub export fn subtract(a: i32, b: i32) i32 {
|
||||||
|
|
||||||
var gAllocator: std.mem.Allocator = undefined;
|
var gAllocator: std.mem.Allocator = undefined;
|
||||||
|
|
||||||
pub fn log(comptime fmt: []const u8, args: anytype) void {
|
|
||||||
core.engine_log("[ExternGame]: " ++ fmt, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_module(args: core.ModuleLoaderArgs) !void {
|
fn start_module(args: core.ModuleLoaderArgs) !void {
|
||||||
if (args.firstLoad) {
|
if (args.firstLoad) {
|
||||||
_ = core.createObject(ExternGameObject, .{}) catch {};
|
_ = core.createObject(ExternGameObject, .{}) catch {};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log("extern game reloaded ", .{});
|
core.logDisplay("externGame", "extern game reloaded ", .{});
|
||||||
log("hello mother fucker", .{});
|
core.logDisplay("externGame", "hello mother fucker", .{});
|
||||||
log("accessing old object at {x} same object? {d}", .{ @intFromPtr(core.EngineObject(ExternGameObject).get()), @sizeOf(ExternGameObject) });
|
core.logDisplay("externGame", "accessing old object at {x} same object? {d}", .{ @intFromPtr(core.EngineObject(ExternGameObject).get()), @sizeOf(ExternGameObject) });
|
||||||
|
|
||||||
log("gonna try something dumb- lets patch the vtable of that old object with my vtable's values", .{});
|
// getting rid of dumb comment
|
||||||
|
//log("gonna try something dumb- lets patch the vtable of that old object with my vtable's values", .{});
|
||||||
const ref = core.getEngineObjectRef(ExternGameObject).?;
|
const ref = core.getEngineObjectRef(ExternGameObject).?;
|
||||||
|
|
||||||
ref.vtable.tick_func = ExternGameObject.NeonObjectTable.tick_func;
|
ref.vtable.tick_func = ExternGameObject.NeonObjectTable.tick_func;
|
||||||
|
|
||||||
|
core.PatchStruct(ExternGameObject, @ptrCast(@alignCast(ref.ptr)), ref.vtable.fieldList.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ExternGameObject = struct {
|
pub const ExternGameObject = struct {
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject");
|
||||||
|
pub const Slack = core.SlackStruct(@This(), 512);
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator = undefined,
|
||||||
|
consoleWindow: imgui.utils.ConsoleWindow = undefined,
|
||||||
|
tbMap: ?*bsp.maploader.TBMap = null,
|
||||||
|
|
||||||
|
//lmao: bool = false,
|
||||||
|
//lmao2: bool = true,
|
||||||
|
a: bool = false,
|
||||||
|
// lib: bool = false,
|
||||||
|
//s: u32 = 0x42,
|
||||||
|
|
||||||
|
pub fn loadMap2(self: *@This()) !void {
|
||||||
|
if (self.tbMap) |tbMap| {
|
||||||
|
core.engine_log("killing the map", .{});
|
||||||
|
tbMap.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tbMap = try bsp.maploader.LoadTrenchbroomMap(self.allocator, .{
|
||||||
|
.rotation = core.Rotation.eulerX(core.radians(-90.0)),
|
||||||
|
.mapName = "bsp/testmap.map",
|
||||||
|
});
|
||||||
|
|
||||||
|
core.engine_log("map loaded", .{});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
const self = try allocator.create(@This());
|
const self = try Slack.create(allocator);
|
||||||
self.* = .{ .allocator = allocator };
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.consoleWindow = imgui.utils.ConsoleWindow.init(allocator),
|
||||||
|
};
|
||||||
|
|
||||||
|
imgui.utils.addMenuFunc(self, "Input Stack Viewer", extras.inputDebugger.windowOpen);
|
||||||
|
self.consoleWindow.setup();
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *@This(), dt: f64) void {
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
_ = dt;
|
|
||||||
_ = self;
|
|
||||||
const rctx = rend.context();
|
const rctx = rend.context();
|
||||||
imgui.utils.structDebugWindow(rctx);
|
_ = dt;
|
||||||
|
|
||||||
|
if (ig.begin("meh", null, .{})) {
|
||||||
|
// if (ig.checkbox("move lights ", null)) {}
|
||||||
|
|
||||||
|
ig.textFmt("info: - WASD to move, mouse to look,\n- Q and E to go up and down", .{}) catch return;
|
||||||
|
ig.textFmt("- shift to slow down camera speed", .{}) catch return;
|
||||||
|
ig.textFmt("- T to enable/disable mouse cursor", .{}) catch return;
|
||||||
|
ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return;
|
||||||
|
ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return;
|
||||||
|
|
||||||
|
if (ig.smallButton("reload map")) {
|
||||||
|
self.loadMap2() catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ig.smallButton("destroy map")) {
|
||||||
|
if (self.tbMap) |tbMap| {
|
||||||
|
core.engine_log("killing the map", .{});
|
||||||
|
tbMap.destroy();
|
||||||
|
self.tbMap = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ig.end();
|
||||||
|
|
||||||
|
//_ = self;
|
||||||
|
_ = rctx;
|
||||||
|
// imgui.utils.structHexView(self);
|
||||||
|
// imgui.utils.structHexView(rctx.activeCamera.?);
|
||||||
// if (ig.begin("external game object", null, .{})) {
|
// if (ig.begin("external game object", null, .{})) {
|
||||||
// ig.textf("sup", .{});
|
// ig.textf("sup", .{});
|
||||||
|
|
||||||
|
|
@ -89,7 +143,7 @@ pub const ExternGameObject = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(Slack.fromPtr(self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -102,3 +156,5 @@ const imgui = backlog.imgui;
|
||||||
const rend = backlog.rend;
|
const rend = backlog.rend;
|
||||||
const ig = imgui.api;
|
const ig = imgui.api;
|
||||||
const platform = backlog.platform;
|
const platform = backlog.platform;
|
||||||
|
const extras = @import("gameExtras");
|
||||||
|
const bsp = @import("bsp");
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ videoFullbright: bool = false,
|
||||||
|
|
||||||
moveLight: bool = true,
|
moveLight: bool = true,
|
||||||
|
|
||||||
rendererDebugger: *extras.RendererDebug = undefined,
|
|
||||||
|
|
||||||
tbMap: ?*bsp.maploader.TBMap = null,
|
tbMap: ?*bsp.maploader.TBMap = null,
|
||||||
|
|
||||||
// addFunc: ?*const fn (i32, i32) callconv(.C) i32 = undefined,
|
// addFunc: ?*const fn (i32, i32) callconv(.C) i32 = undefined,
|
||||||
|
|
@ -150,40 +148,6 @@ pub const DamagedHelmet = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn loadMap2(self: *@This()) !void {
|
|
||||||
if (self.tbMap) |tbMap| {
|
|
||||||
core.engine_log("killing the map", .{});
|
|
||||||
tbMap.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tbMap = try bsp.maploader.LoadTrenchbroomMap(self.allocator, .{
|
|
||||||
.rotation = core.Rotation.eulerX(core.radians(-90.0)),
|
|
||||||
.mapName = "bsp/testmap.map",
|
|
||||||
});
|
|
||||||
|
|
||||||
core.engine_log("map loaded", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn loadMap(self: *@This()) void {
|
|
||||||
self.tbMap = bsp.maploader.LoadTrenchbroomMap(self.allocator, .{
|
|
||||||
.rotation = core.Rotation.eulerX(core.radians(-90.0)),
|
|
||||||
.mapName = "bsp/testmap.map",
|
|
||||||
}) catch |err| {
|
|
||||||
core.engine_log("unable to load map, error: {any}", .{err});
|
|
||||||
self.tbMap = null;
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
core.engine_log("map loaded", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn moduleChangedCallback(pathChanged: []const u8, ctx: ?*anyopaque) void {
|
|
||||||
const self: *@This() = @ptrCast(@alignCast(ctx));
|
|
||||||
|
|
||||||
core.engine_log("moduleChanged {s}", .{pathChanged});
|
|
||||||
var name = core.MakeName(pathChanged);
|
|
||||||
self.modules.put(self.allocator, name.handle(), name.utf8()) catch {};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prepare(self: *@This()) !void {
|
pub fn prepare(self: *@This()) !void {
|
||||||
core.engine_log(">>>>>>> game prepare", .{});
|
core.engine_log(">>>>>>> game prepare", .{});
|
||||||
var z = core.tracy.ZoneN(@src(), "PREPARING GAME");
|
var z = core.tracy.ZoneN(@src(), "PREPARING GAME");
|
||||||
|
|
@ -201,9 +165,11 @@ pub fn prepare(self: *@This()) !void {
|
||||||
|
|
||||||
// try self.tryLoadExtern("externGame");
|
// try self.tryLoadExtern("externGame");
|
||||||
|
|
||||||
self.rendererDebugger = try extras.RendererDebug.create(self.allocator); //try core.createObject(extras.RendererDebug, .{});
|
// self.rendererDebugger = try extras.RendererDebug.create(self.allocator); //try core.createObject(extras.RendererDebug, .{});
|
||||||
|
_ = try core.createObject(extras.RendererDebug, .{});
|
||||||
|
|
||||||
self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
|
//self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
|
||||||
|
self.objectSpawner = try core.createObject(extras.ObjectSpawner, .{});
|
||||||
try self.objectSpawner.addSpawnFunction("fox", FoxObject);
|
try self.objectSpawner.addSpawnFunction("fox", FoxObject);
|
||||||
try self.objectSpawner.addSpawnFunction("doomplayer", DoomPlayer.DoomCanvas);
|
try self.objectSpawner.addSpawnFunction("doomplayer", DoomPlayer.DoomCanvas);
|
||||||
try self.objectSpawner.addSpawnFunction("empire", @import("empire.zig"));
|
try self.objectSpawner.addSpawnFunction("empire", @import("empire.zig"));
|
||||||
|
|
@ -464,78 +430,78 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
// show a window with the current camera's position
|
// show a window with the current camera's position
|
||||||
|
|
||||||
if (!self.mouseLook) {
|
if (!self.mouseLook) {
|
||||||
self.engineTool.tick();
|
// self.engineTool.tick();
|
||||||
self.objectSpawner.windowOpen = !self.mouseLook;
|
self.objectSpawner.windowOpen = !self.mouseLook;
|
||||||
self.objectSpawner.tick(dt);
|
// self.objectSpawner.tick(dt);
|
||||||
extras.inputDebugger.tick();
|
// self.rendererDebugger.tick(dt);
|
||||||
self.rendererDebugger.tick(dt);
|
// if (ig.begin("meh", null, .{})) {
|
||||||
if (ig.begin("meh", null, .{})) {
|
// ig.textFmt("x:{d:.03} y:{d:.03} z:{d:.03}", .{ pos.x, pos.y, pos.z }) catch return;
|
||||||
ig.textFmt("x:{d:.03} y:{d:.03} z:{d:.03}", .{ pos.x, pos.y, pos.z }) catch return;
|
// // if (ig.checkbox("video fullbright", &self.videoFullbright)) {
|
||||||
// if (ig.checkbox("video fullbright", &self.videoFullbright)) {
|
// // //if (self.videoplayerObject.fetch(rend.MeshComponent)) |mesh| {
|
||||||
// //if (self.videoplayerObject.fetch(rend.MeshComponent)) |mesh| {
|
// // // mesh.textureMode.fullbright = self.videoFullbright;
|
||||||
// // mesh.textureMode.fullbright = self.videoFullbright;
|
// // //}
|
||||||
// //}
|
// // }
|
||||||
// }
|
|
||||||
|
|
||||||
if (ig.checkbox("move lights ", &self.moveLight)) {}
|
// if (ig.checkbox("move lights ", &self.moveLight)) {}
|
||||||
|
|
||||||
ig.textFmt("info: - WASD to move, mouse to look,\n- Q and E to go up and down", .{}) catch return;
|
// ig.textFmt("info: - WASD to move, mouse to look,\n- Q and E to go up and down", .{}) catch return;
|
||||||
ig.textFmt("- shift to slow down camera speed", .{}) catch return;
|
// ig.textFmt("- shift to slow down camera speed", .{}) catch return;
|
||||||
ig.textFmt("- T to enable/disable mouse cursor", .{}) catch return;
|
// ig.textFmt("- T to enable/disable mouse cursor", .{}) catch return;
|
||||||
ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return;
|
// ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return;
|
||||||
ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return;
|
// ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return;
|
||||||
|
|
||||||
//ig.textf("1 + 2 = {d}", .{self.addFunc.?(1, 2)});
|
// //ig.textf("1 + 2 = {d}", .{self.addFunc.?(1, 2)});
|
||||||
|
|
||||||
{
|
// {
|
||||||
ig.textf("modules dirty: ", .{});
|
// ig.textf("modules dirty: ", .{});
|
||||||
var i = self.modules.iterator();
|
// var i = self.modules.iterator();
|
||||||
while (i.next()) |n| {
|
// while (i.next()) |n| {
|
||||||
ig.textf("{s} pending reload", .{n.value_ptr.*});
|
// ig.textf("{s} pending reload", .{n.value_ptr.*});
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (ig.smallButton("reload map")) {
|
|
||||||
self.loadMap2() catch unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ig.smallButton("destroy map")) {
|
// if (ig.smallButton("reload map")) {
|
||||||
if (self.tbMap) |tbMap| {
|
// self.loadMap2() catch unreachable;
|
||||||
core.engine_log("killing the map", .{});
|
// }
|
||||||
tbMap.destroy();
|
|
||||||
self.tbMap = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ig.end();
|
|
||||||
|
|
||||||
if (ig.begin("mesh components", null, .{})) {
|
// if (ig.smallButton("destroy map")) {
|
||||||
for (rend.MeshComponent.BaseContainer.dense.items) |*v| {
|
// if (self.tbMap) |tbMap| {
|
||||||
ig.textFmt("mesh: {s}", .{v.value.meshName.utf8()}) catch unreachable;
|
// core.engine_log("killing the map", .{});
|
||||||
}
|
// tbMap.destroy();
|
||||||
}
|
// self.tbMap = null;
|
||||||
ig.end();
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ig.end();
|
||||||
|
|
||||||
if (ig.begin("scene components", null, .{})) {
|
// if (ig.begin("mesh components", null, .{})) {
|
||||||
for (core.Scene.BaseContainer.dense.items) |*v| {
|
// for (rend.MeshComponent.BaseContainer.dense.items) |*v| {
|
||||||
ig.textFmt("scene entity: {d}", .{v.value.handle.index}) catch unreachable;
|
// ig.textFmt("mesh: {s}", .{v.value.meshName.utf8()}) catch unreachable;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
// ig.end();
|
||||||
|
|
||||||
ig.textf("window at 0x{x}", .{@intFromPtr(backlog.platform.context().window)});
|
// if (ig.begin("scene components", null, .{})) {
|
||||||
if (ig.smallButton("click to show sdl messagebox")) {
|
// for (core.Scene.BaseContainer.dense.items) |*v| {
|
||||||
// _ = backlog.platform.windowing.sdl3.c.SDL_ShowSimpleMessageBox(0, "lmao", "you lmaoed your last uwu", backlog.platform.context().window);
|
// ig.textFmt("scene entity: {d}", .{v.value.handle.index}) catch unreachable;
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
ig.end();
|
// ig.textf("window at 0x{x}", .{@intFromPtr(backlog.platform.context().window)});
|
||||||
|
// if (ig.smallButton("click to show sdl messagebox")) {
|
||||||
|
// // _ = backlog.platform.windowing.sdl3.c.SDL_ShowSimpleMessageBox(0, "lmao", "you lmaoed your last uwu", backlog.platform.context().window);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ig.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
self.modules.deinit(self.allocator);
|
self.modules.deinit(self.allocator);
|
||||||
self.rendererDebugger.destroy();
|
// self.rendererDebugger.destroy();
|
||||||
DoomPlayer.DoomCanvas.cleanupDoom();
|
DoomPlayer.DoomCanvas.cleanupDoom();
|
||||||
self.fpcamera.destroy();
|
self.fpcamera.destroy();
|
||||||
|
|
||||||
self.objectSpawner.destroy();
|
// self.objectSpawner.destroy();
|
||||||
// self.videoplayer.destroy();
|
// self.videoplayer.destroy();
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue