make it clear how to use module system without mach.Core (remove mach.App)
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
7ac5bef717
commit
642cc9b7f7
20 changed files with 567 additions and 334 deletions
|
|
@ -22,6 +22,7 @@ pub const components = .{
|
|||
};
|
||||
|
||||
pub const systems = .{
|
||||
.start = .{ .handler = start },
|
||||
.init = .{ .handler = init },
|
||||
.deinit = .{ .handler = deinit },
|
||||
.tick = .{ .handler = tick },
|
||||
|
|
@ -42,6 +43,16 @@ pub fn deinit(core: *mach.Core.Mod, renderer: *Renderer.Mod) void {
|
|||
core.schedule(.deinit);
|
||||
}
|
||||
|
||||
fn start(
|
||||
core: *mach.Core.Mod,
|
||||
renderer: *Renderer.Mod,
|
||||
app: *Mod,
|
||||
) !void {
|
||||
core.schedule(.init);
|
||||
renderer.schedule(.init);
|
||||
app.schedule(.init);
|
||||
}
|
||||
|
||||
fn init(
|
||||
// These are injected dependencies - as long as these modules were registered in the top-level
|
||||
// of the program we can have these types injected here, letting us work with other modules in
|
||||
|
|
@ -49,10 +60,10 @@ fn init(
|
|||
entities: *mach.Entities.Mod,
|
||||
core: *mach.Core.Mod,
|
||||
renderer: *Renderer.Mod,
|
||||
game: *Mod,
|
||||
app: *Mod,
|
||||
) !void {
|
||||
core.schedule(.init);
|
||||
renderer.schedule(.init);
|
||||
core.state().on_tick = app.system(.tick);
|
||||
core.state().on_exit = app.system(.deinit);
|
||||
|
||||
// Create our player entity.
|
||||
const player = try entities.new();
|
||||
|
|
@ -68,9 +79,9 @@ fn init(
|
|||
try renderer.set(player, .scale, 1.0);
|
||||
|
||||
// Initialize our game module's state - these are the struct fields defined at the top of this
|
||||
// file. If this is not done, then game.state() will panic indicating the state was never
|
||||
// file. If this is not done, then app.state() will panic indicating the state was never
|
||||
// initialized.
|
||||
game.init(.{
|
||||
app.init(.{
|
||||
.timer = try mach.Timer.start(),
|
||||
.spawn_timer = try mach.Timer.start(),
|
||||
.player = player,
|
||||
|
|
@ -83,11 +94,11 @@ fn tick(
|
|||
entities: *mach.Entities.Mod,
|
||||
core: *mach.Core.Mod,
|
||||
renderer: *Renderer.Mod,
|
||||
game: *Mod,
|
||||
app: *Mod,
|
||||
) !void {
|
||||
var iter = core.state().pollEvents();
|
||||
var direction = game.state().direction;
|
||||
var spawning = game.state().spawning;
|
||||
var direction = app.state().direction;
|
||||
var spawning = app.state().spawning;
|
||||
while (iter.next()) |event| {
|
||||
switch (event) {
|
||||
.key_press => |ev| {
|
||||
|
|
@ -118,18 +129,18 @@ fn tick(
|
|||
// Keep track of which direction we want the player to move based on input, and whether we want
|
||||
// to be spawning entities.
|
||||
//
|
||||
// Note that game.state() simply returns a pointer to a global singleton of the struct defined
|
||||
// Note that app.state() simply returns a pointer to a global singleton of the struct defined
|
||||
// by this file, so we can access fields defined at the top of this file.
|
||||
game.state().direction = direction;
|
||||
game.state().spawning = spawning;
|
||||
app.state().direction = direction;
|
||||
app.state().spawning = spawning;
|
||||
|
||||
// Get the current player position
|
||||
var player_pos = renderer.get(game.state().player, .position).?;
|
||||
var player_pos = renderer.get(app.state().player, .position).?;
|
||||
|
||||
// If we want to spawn new entities, then spawn them now. The timer just makes spawning rate
|
||||
// independent of frame rate.
|
||||
if (spawning and game.state().spawn_timer.read() > 1.0 / 60.0) {
|
||||
_ = game.state().spawn_timer.lap(); // Reset the timer
|
||||
if (spawning and app.state().spawn_timer.read() > 1.0 / 60.0) {
|
||||
_ = app.state().spawn_timer.lap(); // Reset the timer
|
||||
for (0..5) |_| {
|
||||
// Spawn a new entity at the same position as the player, but smaller in scale.
|
||||
const new_entity = try entities.new();
|
||||
|
|
@ -137,19 +148,19 @@ fn tick(
|
|||
try renderer.set(new_entity, .scale, 1.0 / 6.0);
|
||||
|
||||
// Tag the entity as one that follows the player
|
||||
try game.set(new_entity, .follower, {});
|
||||
try app.set(new_entity, .follower, {});
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply by delta_time to ensure that movement is the same speed regardless of the frame rate.
|
||||
const delta_time = game.state().timer.lap();
|
||||
const delta_time = app.state().timer.lap();
|
||||
|
||||
// Calculate the player position, by moving in the direction the player wants to go
|
||||
// by the speed amount.
|
||||
const speed = 1.0;
|
||||
player_pos.v[0] += direction.x() * speed * delta_time;
|
||||
player_pos.v[1] += direction.y() * speed * delta_time;
|
||||
try renderer.set(game.state().player, .position, player_pos);
|
||||
try renderer.set(app.state().player, .position, player_pos);
|
||||
|
||||
// Query all the entities that have the .follower tag indicating they should follow the player.
|
||||
// TODO(important): better querying API
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const std = @import("std");
|
||||
const mach = @import("mach");
|
||||
|
||||
// The global list of Mach modules registered for use in our application.
|
||||
|
|
@ -7,11 +8,18 @@ pub const modules = .{
|
|||
@import("Renderer.zig"),
|
||||
};
|
||||
|
||||
// TODO: move this to a mach "entrypoint" zig module
|
||||
// TODO: move this to a mach "entrypoint" zig module which handles nuances like WASM requires.
|
||||
pub fn main() !void {
|
||||
// Initialize mach core
|
||||
try mach.core.initModule();
|
||||
const allocator = std.heap.c_allocator;
|
||||
|
||||
// Main loop
|
||||
while (try mach.core.tick()) {}
|
||||
// Initialize module system
|
||||
try mach.mods.init(allocator);
|
||||
|
||||
// Schedule .app.start to run.
|
||||
mach.mods.schedule(.app, .start);
|
||||
|
||||
// Dispatch systems forever or until there are none left to dispatch. If your app uses mach.Core
|
||||
// then this will block forever and never return.
|
||||
const stack_space = try allocator.alloc(u8, 8 * 1024 * 1024);
|
||||
try mach.mods.dispatch(stack_space, .{});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue