Add support for launch args and "dump_shader_translations" arg #59
10
src/main.zig
10
src/main.zig
|
@ -30,12 +30,10 @@ const Player = struct {
|
|||
move_y: ona.act.Axis = .{.keys = .{.w, .s}},
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
try ona.start_app(setup, .{
|
||||
.tick_rate = 60,
|
||||
.execution = .{.thread_share = 0.1},
|
||||
});
|
||||
}
|
||||
pub const main = ona.start(setup, .{
|
||||
.tick_rate = 60,
|
||||
.execution = .{.thread_share = 0.1},
|
||||
});
|
||||
|
||||
fn load(config: ona.Write(ona.gfx.Config), actors: ona.Write(Actors), assets: ona.Write(ona.gfx.Assets)) !void {
|
||||
config.res.width, config.res.height = .{1280, 720};
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
const coral = @import("coral");
|
||||
|
||||
const flow = @import("flow");
|
||||
|
||||
events: *const Events,
|
||||
target_frame_time: f64,
|
||||
elapsed_time: f64,
|
||||
is_running: bool,
|
||||
|
||||
pub const Events = struct {
|
||||
load: flow.World.Event,
|
||||
pre_update: flow.World.Event,
|
||||
update: flow.World.Event,
|
||||
post_update: flow.World.Event,
|
||||
render: flow.World.Event,
|
||||
finish: flow.World.Event,
|
||||
exit: flow.World.Event,
|
||||
};
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn quit(self: *Self) void {
|
||||
self.is_running = false;
|
||||
}
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
const App = @import("./App.zig");
|
||||
|
||||
const coral = @import("coral");
|
||||
|
||||
const flow = @import("flow");
|
||||
|
||||
const gfx = @import("./gfx.zig");
|
||||
|
||||
const msg = @import("./msg.zig");
|
||||
const ona = @import("./ona.zig");
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub const Axis = struct {
|
||||
keys: ?[2]gfx.Input.Key = null,
|
||||
keys: ?[2]ona.gfx.Input.Key = null,
|
||||
};
|
||||
|
||||
pub const Mapping = struct {
|
||||
|
@ -37,7 +33,7 @@ pub const Mapping = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn setup(world: *flow.World, events: App.Events) std.mem.Allocator.Error!void {
|
||||
pub fn setup(world: *flow.World, events: ona.App.Events) std.mem.Allocator.Error!void {
|
||||
try world.set_state(Mapping{});
|
||||
|
||||
try world.on_event(events.pre_update, flow.system_fn(update), .{
|
||||
|
@ -45,7 +41,7 @@ pub fn setup(world: *flow.World, events: App.Events) std.mem.Allocator.Error!voi
|
|||
});
|
||||
}
|
||||
|
||||
pub fn update(inputs: msg.Receive(gfx.Input), mapping: flow.Write(Mapping)) void {
|
||||
pub fn update(inputs: ona.msg.Receive(ona.gfx.Input), mapping: flow.Write(Mapping)) void {
|
||||
mapping.res.keys_pressed = Mapping.ScancodeSet.initEmpty();
|
||||
|
||||
for (inputs.messages()) |message| {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
const App = @import("./App.zig");
|
||||
|
||||
pub const colors = @import("./gfx/colors.zig");
|
||||
|
||||
const coral = @import("coral");
|
||||
|
@ -8,7 +6,7 @@ const ext = @import("./ext.zig");
|
|||
|
||||
const flow = @import("flow");
|
||||
|
||||
const msg = @import("./msg.zig");
|
||||
const ona = @import("./ona.zig");
|
||||
|
||||
const rendering = @import("./gfx/rendering.zig");
|
||||
|
||||
|
@ -437,7 +435,7 @@ fn load_bmp_texture(arena: *std.heap.ArenaAllocator, storage: coral.files.Storag
|
|||
};
|
||||
}
|
||||
|
||||
pub fn poll(app: flow.Write(App), inputs: msg.Send(Input)) !void {
|
||||
pub fn poll(app: flow.Write(ona.App), inputs: ona.msg.Send(Input)) !void {
|
||||
var event = @as(ext.SDL_Event, undefined);
|
||||
|
||||
while (ext.SDL_PollEvent(&event) != 0) {
|
||||
|
@ -450,7 +448,7 @@ pub fn poll(app: flow.Write(App), inputs: msg.Send(Input)) !void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn setup(world: *flow.World, events: App.Events) (error {Unsupported} || std.Thread.SpawnError || std.mem.Allocator.Error)!void {
|
||||
pub fn setup(world: *flow.World, events: ona.App.Events) (error {Unsupported} || std.Thread.SpawnError || std.mem.Allocator.Error)!void {
|
||||
if (ext.SDL_Init(ext.SDL_INIT_VIDEO) != 0) {
|
||||
return error.Unsupported;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ const ext = @cImport({
|
|||
@cInclude("spirv-cross/spirv_cross_c.h");
|
||||
});
|
||||
|
||||
const ona = @import("../ona.zig");
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub const Error = std.mem.Allocator.Error || error {
|
||||
|
@ -283,7 +285,9 @@ pub fn analyze(arena: *std.heap.ArenaAllocator, options: Options) Error!Program
|
|||
try stage.reflect_images_samplers(arena, compiler, resources);
|
||||
try stage.reflect_uniform_blocks(arena, compiler, resources);
|
||||
|
||||
std.log.info("{s}", .{stage.source});
|
||||
if (ona.launch_arg(.dump_shader_translations) != null) {
|
||||
std.log.info("Vertex translated:\n{s}", .{stage.source});
|
||||
}
|
||||
|
||||
break: vertex_stage stage;
|
||||
},
|
||||
|
@ -307,7 +311,9 @@ pub fn analyze(arena: *std.heap.ArenaAllocator, options: Options) Error!Program
|
|||
try stage.reflect_images_samplers(arena, compiler, resources);
|
||||
try stage.reflect_uniform_blocks(arena, compiler, resources);
|
||||
|
||||
std.log.info("{s}", .{stage.source});
|
||||
if (ona.launch_arg(.dump_shader_translations) != null) {
|
||||
std.log.info("Fragment translated:\n{s}", .{stage.source});
|
||||
}
|
||||
|
||||
break: fragment_stage stage;
|
||||
},
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const App = @import("./App.zig");
|
||||
|
||||
const coral = @import("coral");
|
||||
|
||||
const flow = @import("flow");
|
||||
|
||||
const ona = @import("./ona.zig");
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
fn Channel(comptime Message: type) type {
|
||||
|
@ -106,7 +106,7 @@ pub fn Send(comptime Message: type) type {
|
|||
.channel = (try context.register_writable_state_access(TypedChannel)) orelse set: {
|
||||
try context.world.set_state(TypedChannel.init(coral.heap.allocator));
|
||||
|
||||
const app = context.world.get_state(App).?;
|
||||
const app = context.world.get_state(ona.App).?;
|
||||
|
||||
try context.world.on_event(app.events.post_update, flow.system_fn(TypedChannel.swap), .{
|
||||
.label = "swap channel of " ++ @typeName(Message),
|
||||
|
|
179
src/ona/ona.zig
179
src/ona/ona.zig
|
@ -1,5 +1,3 @@
|
|||
pub const App = @import("./App.zig");
|
||||
|
||||
pub const act = @import("./act.zig");
|
||||
|
||||
const coral = @import("coral");
|
||||
|
@ -14,6 +12,35 @@ pub const msg = @import("./msg.zig");
|
|||
|
||||
const std = @import("std");
|
||||
|
||||
pub const App = struct {
|
||||
events: *const Events,
|
||||
target_frame_time: f64,
|
||||
elapsed_time: f64,
|
||||
is_running: bool,
|
||||
|
||||
pub const Events = struct {
|
||||
load: flow.World.Event,
|
||||
pre_update: flow.World.Event,
|
||||
update: flow.World.Event,
|
||||
post_update: flow.World.Event,
|
||||
render: flow.World.Event,
|
||||
finish: flow.World.Event,
|
||||
exit: flow.World.Event,
|
||||
};
|
||||
|
||||
pub fn quit(self: *App) void {
|
||||
self.is_running = false;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Flag = enum {
|
||||
dump_shader_translations,
|
||||
|
||||
var launch_args = [_]?[]const u8{null} ** std.enums.values(Flag).len;
|
||||
|
||||
const values = std.enums.values(Flag);
|
||||
};
|
||||
|
||||
pub const Options = struct {
|
||||
tick_rate: u64,
|
||||
execution: Execution,
|
||||
|
@ -38,79 +65,111 @@ pub const default_middlewares = &.{
|
|||
act.setup,
|
||||
};
|
||||
|
||||
pub fn start_app(setup: Setup, options: Options) anyerror!void {
|
||||
defer {
|
||||
coral.heap.trace_leaks();
|
||||
ext.SDL_Quit();
|
||||
}
|
||||
pub fn launch_arg(flag: Flag) ?[]const u8 {
|
||||
return Flag.launch_args[@intFromEnum(flag)];
|
||||
}
|
||||
|
||||
var world = try switch (options.execution) {
|
||||
.single_threaded => flow.World.init(0),
|
||||
pub fn start(comptime setup: Setup, options: Options) fn () anyerror!void {
|
||||
const Start = struct {
|
||||
fn main() anyerror!void {
|
||||
defer {
|
||||
coral.heap.trace_leaks();
|
||||
ext.SDL_Quit();
|
||||
}
|
||||
|
||||
.thread_share => |thread_share| init: {
|
||||
const cpu_count = @as(u32, @intCast(std.math.clamp(std.Thread.getCpuCount() catch |cpu_count_error| {
|
||||
@panic(switch (cpu_count_error) {
|
||||
error.PermissionDenied => "permission denied retrieving CPU count",
|
||||
error.SystemResources => "system resources are preventing retrieval of the CPU count",
|
||||
error.Unexpected => "unexpected failure retrieving CPU count",
|
||||
});
|
||||
}, 0, std.math.maxInt(u32))));
|
||||
parse_args: for (std.os.argv[1 ..]) |arg| {
|
||||
const arg_span = std.mem.span(arg);
|
||||
const arg_split_index = std.mem.indexOfScalar(u8, arg_span, '=') orelse arg_span.len;
|
||||
const arg_name = arg_span[0 .. arg_split_index];
|
||||
|
||||
break: init flow.World.init(coral.scalars.fractional(cpu_count, thread_share) orelse 0);
|
||||
},
|
||||
};
|
||||
for (Flag.values) |value| {
|
||||
const name = @tagName(value);
|
||||
|
||||
defer world.deinit();
|
||||
if (!std.mem.eql(u8, arg_name, name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const events = App.Events{
|
||||
.load = try world.create_event("load"),
|
||||
.pre_update = try world.create_event("pre-update"),
|
||||
.update = try world.create_event("update"),
|
||||
.post_update = try world.create_event("post-update"),
|
||||
.render = try world.create_event("render"),
|
||||
.finish = try world.create_event("finish"),
|
||||
.exit = try world.create_event("exit"),
|
||||
};
|
||||
Flag.launch_args[@intFromEnum(value)] =
|
||||
if (arg_split_index == arg_span.len)
|
||||
name
|
||||
else
|
||||
arg_span[arg_split_index ..];
|
||||
|
||||
const app = try world.set_get_state(App{
|
||||
.events = &events,
|
||||
.target_frame_time = 1.0 / @as(f64, @floatFromInt(options.tick_rate)),
|
||||
.elapsed_time = 0,
|
||||
.is_running = true,
|
||||
});
|
||||
continue: parse_args;
|
||||
}
|
||||
}
|
||||
|
||||
for (options.middlewares) |setup_middleware| {
|
||||
try setup_middleware(&world, events);
|
||||
}
|
||||
var world = try switch (options.execution) {
|
||||
.single_threaded => flow.World.init(0),
|
||||
|
||||
try setup(&world, events);
|
||||
try world.run_event(events.load);
|
||||
.thread_share => |thread_share| init: {
|
||||
const cpu_count = @as(u32, @intCast(std.math.clamp(std.Thread.getCpuCount() catch |cpu_count_error| {
|
||||
@panic(switch (cpu_count_error) {
|
||||
error.PermissionDenied => "permission denied retrieving CPU count",
|
||||
error.SystemResources => "system resources are preventing retrieval of the CPU count",
|
||||
error.Unexpected => "unexpected failure retrieving CPU count",
|
||||
});
|
||||
}, 0, std.math.maxInt(u32))));
|
||||
|
||||
const ticks_initial = std.time.milliTimestamp();
|
||||
var ticks_previous = ticks_initial;
|
||||
var accumulated_time = @as(f64, 0);
|
||||
break: init flow.World.init(coral.scalars.fractional(cpu_count, thread_share) orelse 0);
|
||||
},
|
||||
};
|
||||
|
||||
while (app.is_running) {
|
||||
const ticks_current = std.time.milliTimestamp();
|
||||
const milliseconds_per_second = 1000.0;
|
||||
const delta_time = @as(f64, @floatFromInt(ticks_current - ticks_previous)) / milliseconds_per_second;
|
||||
defer world.deinit();
|
||||
|
||||
app.elapsed_time = @as(f64, @floatFromInt(ticks_current - ticks_initial)) / milliseconds_per_second;
|
||||
ticks_previous = ticks_current;
|
||||
accumulated_time += delta_time;
|
||||
const events = App.Events{
|
||||
.load = try world.create_event("load"),
|
||||
.pre_update = try world.create_event("pre-update"),
|
||||
.update = try world.create_event("update"),
|
||||
.post_update = try world.create_event("post-update"),
|
||||
.render = try world.create_event("render"),
|
||||
.finish = try world.create_event("finish"),
|
||||
.exit = try world.create_event("exit"),
|
||||
};
|
||||
|
||||
try world.run_event(events.pre_update);
|
||||
const app = try world.set_get_state(App{
|
||||
.events = &events,
|
||||
.target_frame_time = 1.0 / @as(f64, @floatFromInt(options.tick_rate)),
|
||||
.elapsed_time = 0,
|
||||
.is_running = true,
|
||||
});
|
||||
|
||||
while (accumulated_time >= app.target_frame_time) : (accumulated_time -= app.target_frame_time) {
|
||||
try world.run_event(events.update);
|
||||
for (options.middlewares) |setup_middleware| {
|
||||
try setup_middleware(&world, events);
|
||||
}
|
||||
|
||||
try setup(&world, events);
|
||||
try world.run_event(events.load);
|
||||
|
||||
const ticks_initial = std.time.milliTimestamp();
|
||||
var ticks_previous = ticks_initial;
|
||||
var accumulated_time = @as(f64, 0);
|
||||
|
||||
while (app.is_running) {
|
||||
const ticks_current = std.time.milliTimestamp();
|
||||
const milliseconds_per_second = 1000.0;
|
||||
const delta_time = @as(f64, @floatFromInt(ticks_current - ticks_previous)) / milliseconds_per_second;
|
||||
|
||||
app.elapsed_time = @as(f64, @floatFromInt(ticks_current - ticks_initial)) / milliseconds_per_second;
|
||||
ticks_previous = ticks_current;
|
||||
accumulated_time += delta_time;
|
||||
|
||||
try world.run_event(events.pre_update);
|
||||
|
||||
while (accumulated_time >= app.target_frame_time) : (accumulated_time -= app.target_frame_time) {
|
||||
try world.run_event(events.update);
|
||||
}
|
||||
|
||||
try world.run_event(events.post_update);
|
||||
try world.run_event(events.render);
|
||||
try world.run_event(events.finish);
|
||||
}
|
||||
|
||||
try world.run_event(events.exit);
|
||||
}
|
||||
};
|
||||
|
||||
try world.run_event(events.post_update);
|
||||
try world.run_event(events.render);
|
||||
try world.run_event(events.finish);
|
||||
}
|
||||
|
||||
try world.run_event(events.exit);
|
||||
return Start.main;
|
||||
}
|
||||
|
||||
pub const system_fn = flow.system_fn;
|
||||
|
|
Loading…
Reference in New Issue