From 14c2530817f20986b51f611ef637d09f43aac23c Mon Sep 17 00:00:00 2001
From: jjanzen <jjanzen@jjanzen.ca>
Date: Wed, 22 Jan 2025 14:22:12 -0600
Subject: fix memory leak and implement stub front end

---
 src/run.zig | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 src/run.zig

(limited to 'src/run.zig')

diff --git a/src/run.zig b/src/run.zig
new file mode 100644
index 0000000..e20d9b5
--- /dev/null
+++ b/src/run.zig
@@ -0,0 +1,93 @@
+const std = @import("std");
+const stub = @import("frontend/stub.zig");
+const IO = @import("frontend/io_interface.zig").IOInterface;
+const Action = @import("actions.zig").Action;
+
+pub fn run(allocator: std.mem.Allocator, io: *IO) !void {
+    try io.displayMessage("Initialized");
+
+    var action = Action.illegal;
+    var tick_count: usize = 0;
+    while (action != Action.exit) {
+        const str = try std.fmt.allocPrint(allocator, "{}", .{tick_count});
+        defer allocator.free(str);
+        try io.displayMessage(str);
+
+        action = try io.waitForTick();
+        switch (action) {
+            Action.tick => {
+                tick_count += 1;
+            },
+            else => {},
+        }
+    }
+}
+
+test "can run game" {
+    const allocator = std.testing.allocator;
+
+    var as = stub.ActionStack.init(allocator);
+    defer as.deinit();
+
+    var io = try stub.IO.init(allocator, as);
+    defer io.deinit();
+
+    var res: ?anyerror = null;
+    run(allocator, &io) catch |err| {
+        res = err;
+    };
+    try std.testing.expect(res != null);
+    try std.testing.expectEqual(error.NoAvailableAction, res.?);
+}
+
+test "game exits on Action.exit" {
+    const allocator = std.testing.allocator;
+
+    var as = stub.ActionStack.init(allocator);
+    defer as.deinit();
+    try as.scheduleAction(Action.exit);
+
+    var io = try stub.IO.init(allocator, as);
+    defer io.deinit();
+
+    try run(allocator, &io);
+    const io_obj: *const stub.IO = @ptrCast(@alignCast(io.ptr));
+    var actions = io_obj.out_as;
+
+    const act = actions.next().?;
+    try std.testing.expectEqual(Action.exit, act);
+}
+
+test "game processes stream of actions" {
+    const allocator = std.testing.allocator;
+
+    var as = stub.ActionStack.init(allocator);
+    defer as.deinit();
+
+    try as.scheduleAction(Action.exit);
+    try as.scheduleAction(Action.move_right);
+    try as.scheduleAction(Action.move_left);
+    try as.scheduleAction(Action.move_down);
+    try as.scheduleAction(Action.move_up);
+    try as.scheduleAction(Action.tick);
+
+    var io = try stub.IO.init(allocator, as);
+    defer io.deinit();
+
+    try run(allocator, &io);
+    const io_obj: *const stub.IO = @ptrCast(@alignCast(io.ptr));
+    var actions = io_obj.out_as;
+
+    var act = actions.next().?;
+    try std.testing.expectEqual(Action.exit, act);
+    act = actions.next().?;
+    try std.testing.expectEqual(Action.move_right, act);
+    act = actions.next().?;
+    try std.testing.expectEqual(Action.move_left, act);
+    act = actions.next().?;
+    try std.testing.expectEqual(Action.move_down, act);
+    act = actions.next().?;
+    try std.testing.expectEqual(Action.move_up, act);
+    act = actions.next().?;
+    try std.testing.expectEqual(Action.tick, act);
+}
-- 
cgit v1.2.3