adding windowing to sample game's runtime

This commit is contained in:
Peter Li 2025-04-14 15:16:16 -07:00
parent 341e69b32e
commit 9679514ff2
6 changed files with 53 additions and 32 deletions

View File

@ -92,7 +92,6 @@ pub fn run_everything(comptime GameContext: type) !void {
while (!core.gEngine.exitFinished()) {
const z = core.tracy.ZoneN(@src(), "shutdown poll");
platform.getInstance().pollEvents();
z.End();
}
}

View File

@ -172,9 +172,11 @@ pub fn createObject(comptime T: type, params: engine.NeonObjectParams) !*T {
return gEngine.createObject(T, params);
}
pub fn setupEnginePlatform(ctx: *anyopaque, poll: engine.PollFuncFn, proc: engine.ProcEventsFn) void {
gEngine.platformPollFunc = poll;
pub fn setupEnginePlatform(ctx: *anyopaque, setup: engine.SetupFuncFn, poll: engine.PollFuncFn, proc: engine.ProcEventsFn) void {
gEngine.platformCtx = ctx;
gEngine.platformSetupFunc = setup;
gEngine.platformPollFunc = poll;
gEngine.platformProcEventsFunc = proc;
}

View File

@ -26,6 +26,7 @@ const JobManager = jobs.JobManager;
const engine_log = logging.engine_log;
pub const PollFuncFn = *const fn (*anyopaque) EngineDataEventError!void;
pub const SetupFuncFn = *const fn (*anyopaque) EngineDataEventError!void;
pub const ProcEventsFn = *const fn (*anyopaque, u64) EngineDataEventError!void;
const EngineDelegates = @import("EngineDelegates.zig");
@ -66,6 +67,7 @@ pub const Engine = struct {
platformCtx: *anyopaque = undefined,
platformPollFunc: ?PollFuncFn = null,
platformSetupFunc: ?PollFuncFn = null,
platformProcEventsFunc: ?ProcEventsFn = null,
engineStartTime: f64 = 0,
@ -274,6 +276,10 @@ pub const Engine = struct {
var exitSignaled: bool = false;
if (ctx.engine.platformSetupFunc) |setupFunc| {
setupFunc(ctx.engine.platformCtx) catch unreachable;
}
while (true) {
ctx.engine.tick() catch unreachable;
@ -326,11 +332,6 @@ pub const Engine = struct {
fn mainLoop(self: *@This()) !void {
while (!self.exitConfirmed.load(.acquire)) {
if (self.platformPollFunc) |pollFunc| {
const z = core.tracy.ZoneN(@src(), "glfw input polling");
try pollFunc(self.platformCtx);
defer z.End();
}
self.jobManager.bump();
std.time.sleep(1000 * 1000); // 1ms delay between polling functions, effectively limits input to 1khz.
// (there is a noticable power consumption draw on laptops and battery based systems if this is unlimited)

View File

@ -30,7 +30,7 @@ pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std
gPlatformInstance = try allocator.create(windowing.PlatformInstance);
gPlatformInstance.* = try windowing.PlatformInstance.init(allocator, gStartupParams);
try gPlatformInstance.setup();
try gPlatformInstance.registerSetupFuncs();
}
pub fn getInstance() *windowing.PlatformInstance {

View File

@ -62,19 +62,32 @@ pub var gPlatformSettings: struct {
pub const PlatformInstance = struct {
allocator: std.mem.Allocator,
exitSignal: bool = false,
cursorEnabled: bool = true,
newCursorEnabled: bool = true,
hasVideo: bool = false,
window: *sdl3.Window = undefined,
windowExtent: core.Vector2c,
windowName: []u8,
iconPath: []u8,
windowName: [:0]u8,
iconPath: [:0]u8,
windowDestroyed: bool = false,
pub fn deinit(self: *@This()) void {
self.allocator.free(self.windowName);
self.allocator.free(self.iconPath);
// shutdown
}
pub fn onExitSignal(self: *@This()) void {
sdl3.c.SDL_DestroyWindow(self.window);
self.windowDestroyed = true;
}
pub fn readyToExit(self: *@This()) bool {
return self.windowDestroyed;
}
pub fn init(
@ -92,34 +105,40 @@ pub const PlatformInstance = struct {
return self;
}
pub fn setup(self: *@This()) !void {
core.setupEnginePlatform(self, enginePoll, processEvents);
pub fn setupWindow(opaqueSelf: *anyopaque) core.EngineDataEventError!void {
const self: *@This() = @alignCast(@ptrCast(opaqueSelf));
sdl3.init(.{
.video = true,
.gamepad = true,
}) catch return error.BadInit;
self.window = sdl3.c.SDL_CreateWindow(self.windowName, self.windowExtent.x, self.windowExtent.y, 0x20).?; // resizeable
}
pub fn registerSetupFuncs(self: *@This()) !void {
core.setupEnginePlatform(self, setupWindow, enginePoll, processEvents);
}
pub fn enginePoll(opaqueSelf: *anyopaque) core.EngineDataEventError!void {
var self: *@This() = @alignCast(@ptrCast(opaqueSelf));
self.pollEvents();
_ = opaqueSelf;
// var self: *@This() = @alignCast(@ptrCast(opaqueSelf));
// self.pollEvents();
}
pub fn installListener(self: *@This(), listener: anytype) !void {
try self.listeners.append(RawInputObjectRef.from(listener));
}
pub fn pollEvents(self: *@This()) void {
if (self.shouldExit()) {
core.gEngine.exit();
}
}
fn convertEvent(event: *const sdl3.Event) ?IOEvent {
_ = event;
return null;
}
pub fn processEvents(ptr: *anyopaque, frameNumber: u64) core.EngineDataEventError!void {
_ = ptr;
_ = frameNumber;
_ = ptr;
// const self: *@This() = @ptrCast(@alignCast(ptr));
var t1 = tracy.ZoneN(@src(), "Pumping Events");
defer t1.End();
@ -129,6 +148,13 @@ pub const PlatformInstance = struct {
if (convertEvent(event)) |converted| {
inputStack.routeEvent(converted);
}
switch (event.type) {
sdl3.events.quit => {
core.exitNow();
},
else => {},
}
}
}
@ -136,13 +162,6 @@ pub const PlatformInstance = struct {
return self.cursorPos;
}
pub fn shouldExit(self: @This()) bool {
if (self.exitSignal)
return true;
return false;
}
pub fn setCursorEnabled(self: *@This(), cursorEnabled: bool) void {
self.newCursorEnabled = cursorEnabled;
}

2
lib/tracy/build.zig vendored
View File

@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void {
//const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false;
const tracy_enabled: bool = false; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
const tracy_enabled: bool = true; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
// if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| {
// tracy_enabled = with_tracy;
// }