core: simplify event iterator
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
8b8489b3e2
commit
09d39fb694
13 changed files with 46 additions and 74 deletions
|
|
@ -71,8 +71,7 @@ fn init(app: *Mod, core: *mach.Core.Mod) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(core: *mach.Core.Mod, app: *Mod) !void {
|
fn tick(core: *mach.Core.Mod, app: *Mod) !void {
|
||||||
var iter = core.state().pollEvents();
|
while (core.state().nextEvent()) |event| {
|
||||||
while (iter.next()) |event| {
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.close => core.schedule(.exit), // Tell mach.Core to exit the app
|
.close => core.schedule(.exit), // Tell mach.Core to exit the app
|
||||||
else => {},
|
else => {},
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,7 @@ fn init(app: *Mod, core: *mach.Core.Mod) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(core: *mach.Core.Mod, app: *Mod) !void {
|
fn tick(core: *mach.Core.Mod, app: *Mod) !void {
|
||||||
var iter = core.state().pollEvents();
|
while (core.state().nextEvent()) |event| {
|
||||||
while (iter.next()) |event| {
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.close => core.schedule(.exit), // Tell mach.Core to exit the app
|
.close => core.schedule(.exit), // Tell mach.Core to exit the app
|
||||||
else => {},
|
else => {},
|
||||||
|
|
|
||||||
|
|
@ -96,10 +96,9 @@ fn tick(
|
||||||
renderer: *Renderer.Mod,
|
renderer: *Renderer.Mod,
|
||||||
app: *Mod,
|
app: *Mod,
|
||||||
) !void {
|
) !void {
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
var direction = app.state().direction;
|
var direction = app.state().direction;
|
||||||
var spawning = app.state().spawning;
|
var spawning = app.state().spawning;
|
||||||
while (iter.next()) |event| {
|
while (core.state().nextEvent()) |event| {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| {
|
.key_press => |ev| {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
|
|
|
||||||
|
|
@ -110,12 +110,9 @@ fn tick(
|
||||||
glyphs: *Glyphs.Mod,
|
glyphs: *Glyphs.Mod,
|
||||||
app: *Mod,
|
app: *Mod,
|
||||||
) !void {
|
) !void {
|
||||||
// TODO(important): event polling should occur in mach.Core module and get fired as ECS events.
|
|
||||||
// TODO(Core)
|
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
var direction = app.state().direction;
|
var direction = app.state().direction;
|
||||||
var spawning = app.state().spawning;
|
var spawning = app.state().spawning;
|
||||||
while (iter.next()) |event| {
|
while (core.state().nextEvent()) |event| {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| {
|
.key_press => |ev| {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
|
|
|
||||||
|
|
@ -185,9 +185,8 @@ fn tick(
|
||||||
) !void {
|
) !void {
|
||||||
// TODO(important): event polling should occur in mach.Core module and get fired as ECS events.
|
// TODO(important): event polling should occur in mach.Core module and get fired as ECS events.
|
||||||
// TODO(Core)
|
// TODO(Core)
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
var gotta_go_fast = app.state().gotta_go_fast;
|
var gotta_go_fast = app.state().gotta_go_fast;
|
||||||
while (iter.next()) |event| {
|
while (core.state().nextEvent()) |event| {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| {
|
.key_press => |ev| {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
|
|
|
||||||
|
|
@ -104,9 +104,7 @@ fn tick(
|
||||||
audio: *mach.Audio.Mod,
|
audio: *mach.Audio.Mod,
|
||||||
app: *Mod,
|
app: *Mod,
|
||||||
) !void {
|
) !void {
|
||||||
// TODO(Core)
|
while (core.state().nextEvent()) |event| {
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
while (iter.next()) |event| {
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| {
|
.key_press => |ev| {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,7 @@ fn tick(
|
||||||
audio: *mach.Audio.Mod,
|
audio: *mach.Audio.Mod,
|
||||||
app: *Mod,
|
app: *Mod,
|
||||||
) !void {
|
) !void {
|
||||||
// TODO(Core)
|
while (core.state().nextEvent()) |event| {
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
while (iter.next()) |event| {
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| switch (ev.key) {
|
.key_press => |ev| switch (ev.key) {
|
||||||
.down => {
|
.down => {
|
||||||
|
|
|
||||||
|
|
@ -114,12 +114,9 @@ fn tick(
|
||||||
sprite_pipeline: *gfx.SpritePipeline.Mod,
|
sprite_pipeline: *gfx.SpritePipeline.Mod,
|
||||||
app: *Mod,
|
app: *Mod,
|
||||||
) !void {
|
) !void {
|
||||||
// TODO(important): event polling should occur in mach.Core module and get fired as ECS events.
|
|
||||||
// TODO(Core)
|
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
var direction = app.state().direction;
|
var direction = app.state().direction;
|
||||||
var spawning = app.state().spawning;
|
var spawning = app.state().spawning;
|
||||||
while (iter.next()) |event| {
|
while (core.state().nextEvent()) |event| {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| {
|
.key_press => |ev| {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
|
|
|
||||||
|
|
@ -125,12 +125,9 @@ fn tick(
|
||||||
text_pipeline: *gfx.TextPipeline.Mod,
|
text_pipeline: *gfx.TextPipeline.Mod,
|
||||||
app: *Mod,
|
app: *Mod,
|
||||||
) !void {
|
) !void {
|
||||||
// TODO(important): event polling should occur in mach.Core module and get fired as ECS events.
|
|
||||||
// TODO(Core)
|
|
||||||
var iter = core.state().pollEvents();
|
|
||||||
var direction = app.state().direction;
|
var direction = app.state().direction;
|
||||||
var spawning = app.state().spawning;
|
var spawning = app.state().spawning;
|
||||||
while (iter.next()) |event| {
|
while (core.state().nextEvent()) |event| {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.key_press => |ev| {
|
.key_press => |ev| {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
|
|
|
||||||
36
src/Core.zig
36
src/Core.zig
|
|
@ -23,15 +23,7 @@ pub const supports_non_blocking = switch (build_options.core_platform) {
|
||||||
.null => true,
|
.null => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const EventQueue = std.fifo.LinearFifo(Event, .Dynamic);
|
const EventQueue = std.fifo.LinearFifo(Event, .Dynamic);
|
||||||
|
|
||||||
pub const EventIterator = struct {
|
|
||||||
queue: *EventQueue,
|
|
||||||
|
|
||||||
pub fn next(self: *EventIterator) ?Event {
|
|
||||||
return self.queue.readItem();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Set this to true if you intend to drive the main loop yourself.
|
/// Set this to true if you intend to drive the main loop yourself.
|
||||||
///
|
///
|
||||||
|
|
@ -126,8 +118,10 @@ pub const components = .{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callback systems
|
/// Callback system invoked per tick (e.g. per-frame)
|
||||||
on_tick: ?mach.AnySystem = null,
|
on_tick: ?mach.AnySystem = null,
|
||||||
|
|
||||||
|
/// Callback system invoked when application is exiting
|
||||||
on_exit: ?mach.AnySystem = null,
|
on_exit: ?mach.AnySystem = null,
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
@ -156,6 +150,9 @@ surface: *gpu.Surface,
|
||||||
swap_chain: *gpu.SwapChain,
|
swap_chain: *gpu.SwapChain,
|
||||||
descriptor: gpu.SwapChain.Descriptor,
|
descriptor: gpu.SwapChain.Descriptor,
|
||||||
|
|
||||||
|
// Internal state
|
||||||
|
events: EventQueue,
|
||||||
|
|
||||||
// TODO: this needs to be removed.
|
// TODO: this needs to be removed.
|
||||||
pub const InitOptions = struct {
|
pub const InitOptions = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
@ -200,9 +197,13 @@ fn init(core: *Mod, entities: *mach.Entities.Mod) !void {
|
||||||
title[options.title.len] = 0;
|
title[options.title.len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var events = EventQueue.init(allocator);
|
||||||
|
try events.ensureTotalCapacity(8192);
|
||||||
|
|
||||||
core.init(.{
|
core.init(.{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.main_window = main_window,
|
.main_window = main_window,
|
||||||
|
.events = events,
|
||||||
|
|
||||||
// TODO: remove undefined initialization (disgusting!)
|
// TODO: remove undefined initialization (disgusting!)
|
||||||
.platform = undefined,
|
.platform = undefined,
|
||||||
|
|
@ -220,7 +221,8 @@ fn init(core: *Mod, entities: *mach.Entities.Mod) !void {
|
||||||
.descriptor = undefined,
|
.descriptor = undefined,
|
||||||
});
|
});
|
||||||
const state = core.state();
|
const state = core.state();
|
||||||
try Platform.init(&state.platform, options);
|
|
||||||
|
try Platform.init(&state.platform, core, options);
|
||||||
|
|
||||||
state.instance = gpu.createInstance(null) orelse {
|
state.instance = gpu.createInstance(null) orelse {
|
||||||
log.err("failed to create GPU instance", .{});
|
log.err("failed to create GPU instance", .{});
|
||||||
|
|
@ -386,6 +388,7 @@ pub fn deinit(entities: *mach.Entities.Mod, core: *Mod) !void {
|
||||||
state.surface.release();
|
state.surface.release();
|
||||||
state.adapter.release();
|
state.adapter.release();
|
||||||
state.instance.release();
|
state.instance.release();
|
||||||
|
state.events.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const InputState = struct {
|
pub const InputState = struct {
|
||||||
|
|
@ -602,8 +605,10 @@ pub const KeyMods = packed struct(u8) {
|
||||||
_padding: u2 = 0,
|
_padding: u2 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub inline fn pollEvents(core: *@This()) EventIterator {
|
/// Returns the next event until there are no more available. You should check for events during
|
||||||
return .{ .platform = core.platform.pollEvents() };
|
/// every on_tick()
|
||||||
|
pub inline fn nextEvent(core: *@This()) ?Event {
|
||||||
|
return core.events.readItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the window title. The string must be owned by Core, and will not be copied or freed. It is
|
/// Sets the window title. The string must be owned by Core, and will not be copied or freed. It is
|
||||||
|
|
@ -1063,7 +1068,6 @@ comptime {
|
||||||
|
|
||||||
assertHasDecl(Platform, "init");
|
assertHasDecl(Platform, "init");
|
||||||
assertHasDecl(Platform, "deinit");
|
assertHasDecl(Platform, "deinit");
|
||||||
assertHasDecl(Platform, "pollEvents");
|
|
||||||
|
|
||||||
assertHasDecl(Platform, "setTitle");
|
assertHasDecl(Platform, "setTitle");
|
||||||
|
|
||||||
|
|
@ -1104,10 +1108,8 @@ fn assertHasField(comptime T: anytype, comptime field_name: []const u8) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
@import("std").testing.refAllDecls(Platform);
|
_ = Platform;
|
||||||
|
|
||||||
@import("std").testing.refAllDeclsRecursive(InitOptions);
|
@import("std").testing.refAllDeclsRecursive(InitOptions);
|
||||||
@import("std").testing.refAllDeclsRecursive(EventIterator);
|
|
||||||
@import("std").testing.refAllDeclsRecursive(VSyncMode);
|
@import("std").testing.refAllDeclsRecursive(VSyncMode);
|
||||||
@import("std").testing.refAllDeclsRecursive(Size);
|
@import("std").testing.refAllDeclsRecursive(Size);
|
||||||
@import("std").testing.refAllDeclsRecursive(Position);
|
@import("std").testing.refAllDeclsRecursive(Position);
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,7 @@ pub const Darwin = @This();
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
core: *Core,
|
core: *Core,
|
||||||
|
|
||||||
events: Core.EventQueue,
|
|
||||||
input_state: Core.InputState,
|
input_state: Core.InputState,
|
||||||
// modifiers: KeyMods,
|
|
||||||
|
|
||||||
title: [:0]const u8,
|
title: [:0]const u8,
|
||||||
display_mode: DisplayMode,
|
display_mode: DisplayMode,
|
||||||
vsync_mode: VSyncMode,
|
vsync_mode: VSyncMode,
|
||||||
|
|
@ -72,7 +68,12 @@ pub fn run(comptime on_each_update_fn: anytype, args_tuple: std.meta.ArgsTuple(@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on the main thread
|
// Called on the main thread
|
||||||
pub fn init(darwin: *Darwin, options: InitOptions) !void {
|
pub fn init(
|
||||||
|
darwin: *Darwin,
|
||||||
|
core: *Core.Mod,
|
||||||
|
options: InitOptions,
|
||||||
|
) !void {
|
||||||
|
_ = core;
|
||||||
var surface_descriptor = gpu.Surface.Descriptor{};
|
var surface_descriptor = gpu.Surface.Descriptor{};
|
||||||
|
|
||||||
// TODO: support UIKit.
|
// TODO: support UIKit.
|
||||||
|
|
@ -106,13 +107,9 @@ pub fn init(darwin: *Darwin, options: InitOptions) !void {
|
||||||
window.?.makeKeyAndOrderFront(null);
|
window.?.makeKeyAndOrderFront(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var events = EventQueue.init(options.allocator);
|
|
||||||
try events.ensureTotalCapacity(2048);
|
|
||||||
|
|
||||||
darwin.* = .{
|
darwin.* = .{
|
||||||
.allocator = options.allocator,
|
.allocator = options.allocator,
|
||||||
.core = @fieldParentPtr("platform", darwin),
|
.core = @fieldParentPtr("platform", darwin),
|
||||||
.events = events,
|
|
||||||
.input_state = .{},
|
.input_state = .{},
|
||||||
.title = options.title,
|
.title = options.title,
|
||||||
.display_mode = options.display_mode,
|
.display_mode = options.display_mode,
|
||||||
|
|
@ -138,11 +135,6 @@ pub fn update(_: *Darwin) !void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// May be called from any thread.
|
|
||||||
pub inline fn pollEvents(n: *Darwin) Core.EventIterator {
|
|
||||||
return .{ .queue = &n.events };
|
|
||||||
}
|
|
||||||
|
|
||||||
// May be called from any thread.
|
// May be called from any thread.
|
||||||
pub fn setTitle(_: *Darwin, _: [:0]const u8) void {
|
pub fn setTitle(_: *Darwin, _: [:0]const u8) void {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,8 @@ pub const Null = @This();
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
core: *Core,
|
core: *Core,
|
||||||
|
|
||||||
events: Core.EventQueue,
|
|
||||||
input_state: Core.InputState,
|
input_state: Core.InputState,
|
||||||
modifiers: KeyMods,
|
modifiers: KeyMods,
|
||||||
|
|
||||||
title: [:0]u8,
|
title: [:0]u8,
|
||||||
display_mode: DisplayMode,
|
display_mode: DisplayMode,
|
||||||
vsync_mode: VSyncMode,
|
vsync_mode: VSyncMode,
|
||||||
|
|
@ -42,7 +39,14 @@ size: Size,
|
||||||
surface_descriptor: gpu.Surface.Descriptor,
|
surface_descriptor: gpu.Surface.Descriptor,
|
||||||
|
|
||||||
// Called on the main thread
|
// Called on the main thread
|
||||||
pub fn init(_: *Null, _: InitOptions) !void {
|
pub fn init(
|
||||||
|
nul: *Null,
|
||||||
|
core: *Core.Mod,
|
||||||
|
options: InitOptions,
|
||||||
|
) !void {
|
||||||
|
_ = nul;
|
||||||
|
_ = options;
|
||||||
|
_ = core;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,11 +59,6 @@ pub fn update(_: *Null) !void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// May be called from any thread.
|
|
||||||
pub inline fn pollEvents(n: *Null) Core.EventIterator {
|
|
||||||
return .{ .queue = &n.events };
|
|
||||||
}
|
|
||||||
|
|
||||||
// May be called from any thread.
|
// May be called from any thread.
|
||||||
pub fn setTitle(_: *Null, _: [:0]const u8) void {
|
pub fn setTitle(_: *Null, _: [:0]const u8) void {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ surrogate: u16 = 0,
|
||||||
dinput: *w.IDirectInput8W,
|
dinput: *w.IDirectInput8W,
|
||||||
saved_window_rect: w.RECT,
|
saved_window_rect: w.RECT,
|
||||||
surface_descriptor_from_hwnd: gpu.Surface.DescriptorFromWindowsHWND,
|
surface_descriptor_from_hwnd: gpu.Surface.DescriptorFromWindowsHWND,
|
||||||
events: EventQueue,
|
state: *Core,
|
||||||
input_state: Core.InputState,
|
input_state: Core.InputState,
|
||||||
oom: std.Thread.ResetEvent = .{},
|
oom: std.Thread.ResetEvent = .{},
|
||||||
|
|
||||||
|
|
@ -53,11 +53,12 @@ oom: std.Thread.ResetEvent = .{},
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
pub fn init(
|
pub fn init(
|
||||||
self: *Win32,
|
self: *Win32,
|
||||||
|
core: *Core.Mod,
|
||||||
options: InitOptions,
|
options: InitOptions,
|
||||||
) !void {
|
) !void {
|
||||||
|
self.state = core.state();
|
||||||
self.allocator = options.allocator;
|
self.allocator = options.allocator;
|
||||||
self.core = @fieldParentPtr("platform", self);
|
self.core = @fieldParentPtr("platform", self);
|
||||||
self.events = EventQueue.init(self.allocator);
|
|
||||||
self.size = options.size;
|
self.size = options.size;
|
||||||
self.input_state = .{};
|
self.input_state = .{};
|
||||||
self.saved_window_rect = .{ .top = 0, .left = 0, .right = 0, .bottom = 0 };
|
self.saved_window_rect = .{ .top = 0, .left = 0, .right = 0, .bottom = 0 };
|
||||||
|
|
@ -138,7 +139,6 @@ pub fn init(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Win32) void {
|
pub fn deinit(self: *Win32) void {
|
||||||
self.events.deinit();
|
|
||||||
_ = self.dinput.IUnknown_Release();
|
_ = self.dinput.IUnknown_Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,10 +151,6 @@ pub fn update(self: *Win32) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pollEvents(self: *Win32) EventIterator {
|
|
||||||
return .{ .queue = &self.events };
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setTitle(self: *Win32, title: [:0]const u8) void {
|
pub fn setTitle(self: *Win32, title: [:0]const u8) void {
|
||||||
const wtitle = std.unicode.utf8ToUtf16LeAllocZ(self.allocator, title) catch {
|
const wtitle = std.unicode.utf8ToUtf16LeAllocZ(self.allocator, title) catch {
|
||||||
self.oom.set();
|
self.oom.set();
|
||||||
|
|
@ -316,7 +312,7 @@ pub fn outOfMemory(self: *Win32) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pushEvent(self: *Win32, event: Event) void {
|
fn pushEvent(self: *Win32, event: Event) void {
|
||||||
self.events.writeItem(event) catch self.oom.set();
|
self.state.events.writeItem(event) catch self.oom.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getKeyboardModifiers() mach.Core.KeyMods {
|
fn getKeyboardModifiers() mach.Core.KeyMods {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue