Game
now uses execution graph to schedule systems
This commit is contained in:
102
src/game.zig
102
src/game.zig
@@ -1,48 +1,90 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const sdl = @import("sdl");
|
||||
const Graph = @import("graph.zig");
|
||||
const Graphics = @import("graphics.zig");
|
||||
|
||||
graphics: Graphics,
|
||||
running: bool,
|
||||
// TODO:
|
||||
// - Do something about deallocating `Resource`s when `Graph` fails
|
||||
|
||||
const RunInfo = struct { running: bool };
|
||||
|
||||
alloc: std.mem.Allocator,
|
||||
graph: Graph,
|
||||
|
||||
const Self = @This();
|
||||
pub fn init() GameError!Self {
|
||||
pub fn init(alloc: std.mem.Allocator) GameError!Self {
|
||||
var graph = try Graph.init(alloc);
|
||||
errdefer graph.deinit();
|
||||
|
||||
const graphics = try Graphics.create();
|
||||
|
||||
var controller = try graph.getController();
|
||||
controller.addResource(graphics);
|
||||
try graph.freeController(controller);
|
||||
|
||||
return Self{
|
||||
.graphics = try Graphics.create(),
|
||||
.running = false,
|
||||
.alloc = alloc,
|
||||
.graph = graph,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn run(self: *Self) GameError!void {
|
||||
self.running = true;
|
||||
{
|
||||
var controller = try self.graph.getController();
|
||||
controller.addResource(RunInfo{ .running = true });
|
||||
try self.graph.freeController(controller);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try self.processEvents();
|
||||
if (!self.running) {
|
||||
if (!self.graph.getResource(RunInfo).?.running) {
|
||||
break;
|
||||
}
|
||||
try self.update();
|
||||
try self.draw();
|
||||
|
||||
var controller = try self.graph.getController();
|
||||
controller.queue(.{
|
||||
.events = processEvents,
|
||||
.draw = draw,
|
||||
.ordered = true,
|
||||
});
|
||||
try self.graph.freeController(controller);
|
||||
|
||||
defer self.graph.reset();
|
||||
try self.graph.runAllSystems();
|
||||
}
|
||||
}
|
||||
|
||||
fn update(self: *Self) GameError!void {
|
||||
_ = self;
|
||||
fn draw(graphics: *Graphics) GameError!void {
|
||||
try graphics.beginDraw();
|
||||
{
|
||||
errdefer graphics.endDraw() catch {};
|
||||
try graphics.drawDebug();
|
||||
}
|
||||
try graphics.endDraw();
|
||||
}
|
||||
|
||||
fn draw(self: *Self) GameError!void {
|
||||
try self.graphics.beginDraw();
|
||||
try self.graphics.drawDebug();
|
||||
try self.graphics.endDraw();
|
||||
fn clean(graphics: *Graphics) !void {
|
||||
graphics.destroy();
|
||||
// TODO: Also remove the resource
|
||||
}
|
||||
|
||||
fn processEvents(self: *Self) GameError!void {
|
||||
fn processEvents(graphics: *Graphics, run_info: *RunInfo) GameError!void {
|
||||
sdl.PumpEvents();
|
||||
while (true) {
|
||||
var buffer: [16]sdl.Event = undefined;
|
||||
const count: usize = @intCast(sdl.PeepEvents(&buffer, buffer.len, sdl.GETEVENT, sdl.EVENT_FIRST, sdl.EVENT_LAST));
|
||||
if (count == -1) return GameError.SdlError;
|
||||
for (buffer[0..count]) |event| {
|
||||
self.processEvent(event);
|
||||
switch (event.type) {
|
||||
sdl.EVENT_QUIT => {
|
||||
run_info.running = false;
|
||||
},
|
||||
sdl.EVENT_WINDOW_RESIZED => {
|
||||
if (event.window.windowID != sdl.GetWindowID(graphics.window)) return;
|
||||
graphics.resize(@intCast(event.window.data1), @intCast(event.window.data2));
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
if (count < buffer.len) {
|
||||
break;
|
||||
@@ -51,25 +93,21 @@ fn processEvents(self: *Self) GameError!void {
|
||||
sdl.FlushEvents(sdl.EVENT_FIRST, sdl.EVENT_LAST);
|
||||
}
|
||||
|
||||
fn processEvent(self: *Self, event: sdl.Event) void {
|
||||
switch (event.type) {
|
||||
sdl.EVENT_QUIT => {
|
||||
self.running = false;
|
||||
},
|
||||
sdl.EVENT_WINDOW_RESIZED => {
|
||||
if (event.window.windowID != sdl.GetWindowID(self.graphics.window)) return;
|
||||
self.graphics.resize(@intCast(event.window.data1), @intCast(event.window.data2));
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.graphics.destroy();
|
||||
var controller = self.graph.getController() catch unreachable;
|
||||
controller.queue(clean);
|
||||
self.graph.freeController(controller) catch unreachable;
|
||||
self.graph.runAllSystems() catch unreachable;
|
||||
|
||||
self.graph.deinit();
|
||||
|
||||
sdl.Quit();
|
||||
}
|
||||
|
||||
pub const GameError = error{
|
||||
SdlError,
|
||||
OSError,
|
||||
OutOfMemory,
|
||||
MissingResource,
|
||||
SystemDeadlock,
|
||||
};
|
||||
|
Reference in New Issue
Block a user