ona/demos/inputs.zig

130 lines
3.5 KiB
Zig
Raw Normal View History

const gfx = @import("gfx");
const hid = @import("hid");
const ona = @import("ona");
const std = @import("std");
const Spawned = struct {
transform: gfx.Transform2D,
lifetime_seconds: f32,
};
const Visuals = struct {
spawned_keyboards: ona.stack.Parallel(Spawned) = .{},
spawned_mouses: ona.stack.Parallel(Spawned) = .{},
keyboard_icon: gfx.Texture = .default,
mouse_icon: gfx.Texture = .default,
random: std.Random.Xoroshiro128,
mouse_position: @Vector(2, f32) = @splat(0),
};
fn cleanup(visuals: ona.Write(Visuals)) !void {
visuals.state.spawned_keyboards.deinit();
visuals.state.spawned_mouses.deinit();
}
fn load(visuals: ona.Write(Visuals)) !void {
const initial_spawn_capacity = 1024;
try visuals.state.spawned_keyboards.grow(initial_spawn_capacity);
try visuals.state.spawned_mouses.grow(initial_spawn_capacity);
}
pub const main = ona.App.setup.
with_module(gfx).
with_module(hid).
with_state(Visuals{.random = std.Random.Xoroshiro128.init(47342563891212)}).
with_system(.load, ona.system_fn(load), .{.label = "load visuals"}).
with_system(.update, ona.system_fn(update), .{.label = "spawn visuals"}).
with_system(.render, ona.system_fn(render), .{.label = "render visuals"}).
with_system(.exit, ona.system_fn(cleanup), .{.label = "clean up visuals"}).build();
fn update(visuals: ona.Write(Visuals), events: ona.Receive(hid.Event), display: ona.Read(gfx.Display)) !void {
update_spawned(&visuals.state.spawned_keyboards);
update_spawned(&visuals.state.spawned_mouses);
const random = visuals.state.random.random();
const width: f32 = @floatFromInt(display.state.width);
const height: f32 = @floatFromInt(display.state.height);
const icon_scale = .{8, 8};
for (events.messages()) |event| {
switch (event) {
.key_down => {
try visuals.state.spawned_keyboards.push_grow(.{
.lifetime_seconds = 2.5 + (5 * random.float(f32)),
.transform = gfx.transform_2d(.{
.translation = .{width * random.float(f32), height},
.rotation = std.math.pi * random.float(f32),
.scale = icon_scale,
}),
});
},
.mouse_down => {
try visuals.state.spawned_mouses.push_grow(.{
.lifetime_seconds = 2.5 + (5 * random.float(f32)),
.transform = gfx.transform_2d(.{
.translation = visuals.state.mouse_position,
.rotation = std.math.pi * random.float(f32),
.scale = icon_scale,
}),
});
},
.mouse_motion => |motion| {
visuals.state.mouse_position = motion.absolute_position;
},
else => {}
}
}
}
fn update_spawned(spawned: *ona.stack.Parallel(Spawned)) void {
const float_speed = 6;
for (spawned.values.slice(.transform)) |*transform| {
transform.* = transform.translated(.{0, -float_speed});
}
{
var range = spawned.len();
var index: usize = 0;
while (index < range) : (index += 1) {
const lifetime_seconds = spawned.values.get(.lifetime_seconds, index).?;
lifetime_seconds.* -= 1.0 / 60.0;
if (lifetime_seconds.* <= 0) {
range -= 1;
std.mem.swap(f32, lifetime_seconds, spawned.values.get(.lifetime_seconds, range).?);
}
}
std.debug.assert(spawned.pop_many(spawned.len() - range));
}
}
fn render(visuals: ona.Write(Visuals), commands: gfx.Commands) !void {
for (visuals.state.spawned_keyboards.values.slice(.transform)) |transform| {
try commands.draw_texture(.{
.texture = visuals.state.keyboard_icon,
.transform = transform,
});
}
for (visuals.state.spawned_mouses.values.slice(.transform)) |transform| {
try commands.draw_texture(.{
.texture = visuals.state.keyboard_icon,
.transform = transform,
});
}
}