From 5e2ac5f3fea446a1058613d62ceb99910a97a36e Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Thu, 2 May 2024 18:39:59 +0200 Subject: [PATCH] Refactored OpaquePtr/Scene slightly. Removed unused allegro.path. --- allegro.path | 0 src/context.zig | 16 ++++-- src/engine/opaque_ptr.zig | 31 ++++++---- src/engine/scene.zig | 115 ++++++++++++++++++++++++-------------- src/main.zig | 3 +- src/main_menu_scene.zig | 2 +- src/title_scene.zig | 2 +- 7 files changed, 106 insertions(+), 63 deletions(-) delete mode 100644 allegro.path diff --git a/allegro.path b/allegro.path deleted file mode 100644 index e69de29..0000000 diff --git a/src/context.zig b/src/context.zig index 5055488..3004cb7 100644 --- a/src/context.zig +++ b/src/context.zig @@ -65,6 +65,13 @@ pub const Context = struct { }; } + pub fn enterScene(self: *Context, scene: Scene) void { + self.exitScene(); + + self.scene = scene; + scene.enter(self); + } + fn exitScene(self: *Context) void { if (self.scene) |scene| { scene.exit(self); @@ -83,11 +90,8 @@ pub const Context = struct { self.shouldQuit = true; } - pub fn switchToScene(self: *Context, comptime SceneType: type, build: ?*const fn (*SceneType) void) !void { - self.exitScene(); - - const scene = try Scene.init(SceneType, self.allocator, build); - self.scene = scene; - scene.enter(self); + pub fn switchToScene(self: *Context, comptime SceneType: type) !void { + const scene = try Scene.init(SceneType, self.allocator); + self.enterScene(scene); } }; diff --git a/src/engine/opaque_ptr.zig b/src/engine/opaque_ptr.zig index 5248fa7..013c0bd 100644 --- a/src/engine/opaque_ptr.zig +++ b/src/engine/opaque_ptr.zig @@ -3,7 +3,7 @@ const Allocator = std.mem.Allocator; pub const OpaquePtr = struct { allocator: Allocator, - object: usize = undefined, + ptr: usize = undefined, virtualTable: VirtualTable = undefined, const VirtualTable = struct { @@ -13,28 +13,37 @@ pub const OpaquePtr = struct { pub fn Object(comptime Type: type) type { return struct { ptr: *Type, - opaquePtr: OpaquePtr, + opaque_ptr: OpaquePtr, }; } - pub fn create(comptime Type: type, allocator: Allocator) !Object(Type) { + pub fn create(comptime Type: type, allocator: Allocator) !OpaquePtr { const ptr = try allocator.create(Type); - const opaq = OpaquePtr{ + return OpaquePtr.init(Type, allocator, ptr); + } + + pub fn createObject(comptime Type: type, allocator: Allocator) !Object(Type) { + const ptr = try allocator.create(Type); + const opaq = OpaquePtr.init(Type, allocator, ptr); + return Object(Type){ + .ptr = ptr, + .opaque_ptr = opaq, + }; + } + + fn init(comptime Type: type, allocator: Allocator, ptr: *Type) OpaquePtr { + return OpaquePtr{ .allocator = allocator, - .object = @intFromPtr(ptr), + .ptr = @intFromPtr(ptr), .virtualTable = .{ .destroy = struct { fn destroy(self: OpaquePtr) void { - const object = @as(*Type, @ptrFromInt(self.object)); - self.allocator.destroy(object); + const p = @as(*Type, @ptrFromInt(self.ptr)); + self.allocator.destroy(p); } }.destroy, }, }; - return Object(Type){ - .ptr = ptr, - .opaquePtr = opaq, - }; } pub fn destroy(self: OpaquePtr) void { diff --git a/src/engine/scene.zig b/src/engine/scene.zig index 5728b20..f5750b1 100644 --- a/src/engine/scene.zig +++ b/src/engine/scene.zig @@ -5,9 +5,9 @@ pub fn Scene(comptime Context: type, comptime Event: type) type { return struct { const Self = @This(); - object: usize = undefined, + scene_ptr: usize = undefined, virtualTable: VirtualTable = undefined, - opaquePtr: ?OpaquePtr = null, + opaque_ptr: ?OpaquePtr = null, const VirtualTable = struct { enter: *const fn (Self, *Context) void, @@ -37,52 +37,81 @@ pub fn Scene(comptime Context: type, comptime Event: type) type { self.virtualTable.tick(self, ctx, t, dt); } - pub fn makeOpaque(comptime SceneType: type, object: *SceneType) Self { - return Self{ .object = @intFromPtr(object), .virtualTable = .{ - .enter = struct { - fn enter(self: Self, ctx: *Context) void { - const scene = @as(*SceneType, @ptrFromInt(self.object)); - scene.enter(ctx); - } - }.enter, - .exit = struct { - fn exit(self: Self, ctx: *Context) void { - const scene = @as(*SceneType, @ptrFromInt(self.object)); - scene.exit(ctx); - } - }.exit, - .handle = struct { - fn handle(self: Self, ctx: *Context, event: Event) !void { - const scene = @as(*SceneType, @ptrFromInt(self.object)); - try scene.handle(ctx, event); - } - }.handle, - .tick = struct { - fn tick(self: Self, ctx: *Context, t: f32, dt: f32) void { - const scene = @as(*SceneType, @ptrFromInt(self.object)); - scene.tick(ctx, t, dt); - } - }.tick, - .render = struct { - fn render(self: Self, ctx: *Context) void { - const scene = @as(*SceneType, @ptrFromInt(self.object)); - scene.render(ctx); - } - }.render, - } }; + pub fn Builder(comptime SceneType: type) type { + return struct { + const SelfBuilder = @This(); + + pub const Object = struct { + ptr: *SceneType, + opaque_ptr: Scene, + }; + + pub fn init(allocator: std.mem.Allocator) !Self { + const ptr = try OpaquePtr.create(SceneType, allocator); + return SelfBuilder.initOpaque(ptr); + } + + pub fn initBuild(allocator: std.mem.Allocator, build: *const fn (*SceneType) void) !Self { + const ptr = try OpaquePtr.createObject(SceneType, allocator); + build(ptr.ptr); + return SelfBuilder.initOpaque(ptr.opaque_ptr); + } + + pub fn initObject(allocator: std.mem.Allocator) !Object { + const ptr = try OpaquePtr.createObject(SceneType, allocator); + return Object{ + .ptr = ptr.ptr, + .opaque_ptr = SelfBuilder.initOpaque(ptr.opaque_ptr), + }; + } + + pub fn initOpaque(ptr: OpaquePtr) Self { + return Self{ + .scene_ptr = ptr.ptr, + .virtualTable = .{ + .enter = struct { + fn enter(self: Self, ctx: *Context) void { + const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr)); + scene.enter(ctx); + } + }.enter, + .exit = struct { + fn exit(self: Self, ctx: *Context) void { + const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr)); + scene.exit(ctx); + } + }.exit, + .handle = struct { + fn handle(self: Self, ctx: *Context, event: Event) !void { + const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr)); + try scene.handle(ctx, event); + } + }.handle, + .tick = struct { + fn tick(self: Self, ctx: *Context, t: f32, dt: f32) void { + const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr)); + scene.tick(ctx, t, dt); + } + }.tick, + .render = struct { + fn render(self: Self, ctx: *Context) void { + const scene = @as(*SceneType, @ptrFromInt(self.scene_ptr)); + scene.render(ctx); + } + }.render, + }, + .opaque_ptr = ptr, + }; + } + }; } - pub fn init(comptime SceneType: type, allocator: std.mem.Allocator, build: ?*const fn (*SceneType) void) !Self { - const object = try OpaquePtr.create(SceneType, allocator); - const scene = Self.makeOpaque(SceneType, object.ptr); - if (build) |b| { - b(object.ptr); - } - return scene; + pub fn init(comptime SceneType: type, allocator: std.mem.Allocator) !Self { + return Builder(SceneType).init(allocator); } pub fn deinit(self: Self) void { - if (self.opaquePtr) |ptr| { + if (self.opaque_ptr) |ptr| { ptr.destroy(); } } diff --git a/src/main.zig b/src/main.zig index 0d9b21d..3ad0181 100644 --- a/src/main.zig +++ b/src/main.zig @@ -7,6 +7,7 @@ const Context = @import("context.zig").Context; const GameScene = @import("game_scene.zig").GameScene; const Palette = @import("palette.zig").Palette; const Renderer = @import("renderer.zig").Renderer; +const Scene = @import("scene.zig").Scene; const TitleScene = @import("title_scene.zig").TitleScene; fn hexColor(hex: []const u8) allegro.Color { @@ -63,7 +64,7 @@ pub fn main() !void { try renderer.registerFonts(); - try context.switchToScene(TitleScene, null); + context.switchToScene(TitleScene) catch unreachable; var t = allegro.getTime(); const fpsBuffer = [_]u8{0} ** 32; diff --git a/src/main_menu_scene.zig b/src/main_menu_scene.zig index f8707ed..f1a8d65 100644 --- a/src/main_menu_scene.zig +++ b/src/main_menu_scene.zig @@ -18,7 +18,7 @@ pub const MainMenuScene = struct { switch (event.type) { allegro.c.ALLEGRO_EVENT_KEY_CHAR => { switch (event.keyboard.keycode) { - allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(GameScene, null), + allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(GameScene), else => {}, } }, diff --git a/src/title_scene.zig b/src/title_scene.zig index 267aaa6..5c79441 100644 --- a/src/title_scene.zig +++ b/src/title_scene.zig @@ -19,7 +19,7 @@ pub const TitleScene = struct { switch (event.type) { allegro.c.ALLEGRO_EVENT_KEY_CHAR => { switch (event.keyboard.keycode) { - allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(MainMenuScene, null), + allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(MainMenuScene), else => {}, } },