Refactored OpaquePtr/Scene slightly.

Removed unused allegro.path.
This commit is contained in:
Sander Schobers 2024-05-02 18:39:59 +02:00
parent 93d9fe6c12
commit 5e2ac5f3fe
7 changed files with 106 additions and 63 deletions

View File

View File

@ -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);
}
};

View File

@ -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 {

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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 => {},
}
},

View File

@ -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 => {},
}
},