|
|
|
@ -2,15 +2,18 @@ const std = @import("std"); |
|
|
|
|
const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator(.{}); |
|
|
|
|
|
|
|
|
|
const core = @import("mach").core; |
|
|
|
|
const Renderer = @import("./Renderer.zig"); |
|
|
|
|
const Renderer = @import("./renderer.zig"); |
|
|
|
|
|
|
|
|
|
const flecszigble = @import("flecs-zig-ble"); |
|
|
|
|
const flecs = flecszigble.flecs; |
|
|
|
|
|
|
|
|
|
const Context = flecszigble.Context(void); |
|
|
|
|
const World = Context.World; |
|
|
|
|
const Iter = Context.Iter; |
|
|
|
|
|
|
|
|
|
const flecs = flecszigble.flecs; |
|
|
|
|
const OnLoad = flecs.pipeline.OnLoad; |
|
|
|
|
const OnUpdate = flecs.pipeline.OnUpdate; |
|
|
|
|
const OnStore = flecs.pipeline.OnStore; |
|
|
|
|
|
|
|
|
|
pub const App = @This(); |
|
|
|
|
|
|
|
|
|
gpa: GeneralPurposeAllocator, |
|
|
|
@ -54,10 +57,14 @@ pub fn init(app: *App) !void { |
|
|
|
|
app.world = world; |
|
|
|
|
|
|
|
|
|
// Create a singleton component for accessing the `App` from ECS. |
|
|
|
|
_ = try world.singleton(*App, app); |
|
|
|
|
_ = try world.singleton("App", *App, app); |
|
|
|
|
|
|
|
|
|
// TODO: The way we register systems using flecs-zig-ble is still very WIP. |
|
|
|
|
_ = try world.system("PollEvents", pollEvents, OnLoad, "App"); |
|
|
|
|
|
|
|
|
|
_ = try world.system(PollEvents); |
|
|
|
|
_ = try world.system(UpdateWindowTitle); |
|
|
|
|
const s = try world.system("UpdateWindowTitle", updateWindowTitle, OnStore, ""); |
|
|
|
|
// Set the update interval of the `UpdateWindowTitle` system to 1 second. |
|
|
|
|
_ = flecszigble.c.ecs_set_interval(world.raw, s.raw, 1.0); |
|
|
|
|
|
|
|
|
|
app.renderer = try Renderer.init(app); |
|
|
|
|
} |
|
|
|
@ -77,36 +84,30 @@ pub fn update(app: *App) !bool { |
|
|
|
|
return !app.world.progress(0.0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// System that reads events from the OS such as input. |
|
|
|
|
pub const PollEvents = struct { |
|
|
|
|
pub const phase = flecs.pipeline.OnLoad; |
|
|
|
|
pub const expr = "App($)"; |
|
|
|
|
pub fn callback(world: *World, app: *const *App) void { |
|
|
|
|
/// Read events from the OS such as input. |
|
|
|
|
pub fn pollEvents(it: Iter) void { |
|
|
|
|
const app = it.field(*App, 1)[0]; |
|
|
|
|
|
|
|
|
|
var pollIter = core.pollEvents(); |
|
|
|
|
while (pollIter.next()) |event| { |
|
|
|
|
switch (event) { |
|
|
|
|
// Allow the renderer to act on the window being resized. |
|
|
|
|
// This is required so we can resize necessary buffers. |
|
|
|
|
.framebuffer_resize => |_| app.*.renderer.resize(), |
|
|
|
|
.framebuffer_resize => |_| app.renderer.resize(), |
|
|
|
|
|
|
|
|
|
// Close the window when requested, such as when |
|
|
|
|
// pressing the X button in the window title bar. |
|
|
|
|
.close => world.quit(), |
|
|
|
|
.close => it.world.quit(), |
|
|
|
|
|
|
|
|
|
else => {}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/// System that updates the window title to show FPS and input frequency. |
|
|
|
|
pub const UpdateWindowTitle = struct { |
|
|
|
|
pub const phase = flecs.pipeline.OnStore; |
|
|
|
|
pub const interval = 1.0; // Run only once a second. |
|
|
|
|
pub fn callback(_: Iter) void { |
|
|
|
|
/// Update the window title to show FPS and input frequency. |
|
|
|
|
pub fn updateWindowTitle(_: Iter) void { |
|
|
|
|
core.printTitle( |
|
|
|
|
"Triangle [ {d}fps ] [ Input {d}hz ]", |
|
|
|
|
.{ core.frameRate(), core.inputRate() }, |
|
|
|
|
) catch @panic("Title too long!"); |
|
|
|
|
} |
|
|
|
|
}; |