unify mach.Call and mach.Runner into one type
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
14ccd5a93c
commit
8054d03b4d
19 changed files with 125 additions and 97 deletions
|
|
@ -23,11 +23,10 @@ pub fn deinit(app: *App) void {
|
||||||
pub fn init(
|
pub fn init(
|
||||||
app: *App,
|
app: *App,
|
||||||
core: *mach.Core,
|
core: *mach.Core,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// Create our shader module
|
// Create our shader module
|
||||||
const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
|
const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,10 @@ pipeline: *gpu.RenderPipeline,
|
||||||
pub fn init(
|
pub fn init(
|
||||||
core: *mach.Core,
|
core: *mach.Core,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
// app_caller: mach.Caller(App),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
// core.on_tick = app_caller.tick;
|
|
||||||
// core.on_exit = app_caller.exit;
|
|
||||||
|
|
||||||
// Create our shader module
|
// Create our shader module
|
||||||
const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
|
const shader_module = core.device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ direction: Vec2 = vec2(0, 0),
|
||||||
spawning: bool = false,
|
spawning: bool = false,
|
||||||
spawn_timer: mach.time.Timer,
|
spawn_timer: mach.time.Timer,
|
||||||
|
|
||||||
// Components our game module defines.
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
// Whether an entity is a "follower" of our player entity or not. The type is void because we
|
// Whether an entity is a "follower" of our player entity or not. The type is void because we
|
||||||
// don't need any information, this is just a tag we assign to an entity with no data.
|
// don't need any information, this is just a tag we assign to an entity with no data.
|
||||||
|
|
@ -49,11 +49,10 @@ fn init(
|
||||||
core: *mach.Core,
|
core: *mach.Core,
|
||||||
renderer: *Renderer,
|
renderer: *Renderer,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// Create our player entity.
|
// Create our player entity.
|
||||||
const player = try entities.new();
|
const player = try entities.new();
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ uniform_buffer: *gpu.Buffer,
|
||||||
|
|
||||||
pub const mach_module = .renderer;
|
pub const mach_module = .renderer;
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.position = .{ .type = Vec3 },
|
.position = .{ .type = Vec3 },
|
||||||
.rotation = .{ .type = Vec3 },
|
.rotation = .{ .type = Vec3 },
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,10 @@ fn init(
|
||||||
glyphs: *Glyphs.Mod,
|
glyphs: *Glyphs.Mod,
|
||||||
app: *App,
|
app: *App,
|
||||||
core: *mach.Core,
|
core: *mach.Core,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// Create a sprite rendering pipeline
|
// Create a sprite rendering pipeline
|
||||||
const texture = glyphs.state().texture;
|
const texture = glyphs.state().texture;
|
||||||
|
|
|
||||||
|
|
@ -80,12 +80,10 @@ fn init(
|
||||||
text: *gfx.Text.Mod,
|
text: *gfx.Text.Mod,
|
||||||
sprite_pipeline: *gfx.SpritePipeline.Mod,
|
sprite_pipeline: *gfx.SpritePipeline.Mod,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
app_audio_state_change: mach.Call(App, .audio_state_change),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// Configure the audio module to run our audio_state_change system when entities audio finishes
|
// Configure the audio module to run our audio_state_change system when entities audio finishes
|
||||||
// playing
|
// playing
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ pub const mach_systems = .{ .start, .init, .deinit, .tick, .audio_state_change }
|
||||||
// TODO: banish global allocator
|
// TODO: banish global allocator
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.play_after = .{ .type = f32 },
|
.play_after = .{ .type = f32 },
|
||||||
};
|
};
|
||||||
|
|
@ -41,12 +42,10 @@ fn init(
|
||||||
core: *mach.Core,
|
core: *mach.Core,
|
||||||
audio: *mach.Audio,
|
audio: *mach.Audio,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
app_audio_state_change: mach.Call(App, .audio_state_change),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// Configure the audio module to send our app's .audio_state_change event when an entity's sound
|
// Configure the audio module to send our app's .audio_state_change event when an entity's sound
|
||||||
// finishes playing.
|
// finishes playing.
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ pub const mach_module = .app;
|
||||||
|
|
||||||
pub const mach_systems = .{ .start, .init, .deinit, .tick, .audio_state_change };
|
pub const mach_systems = .{ .start, .init, .deinit, .tick, .audio_state_change };
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.is_bgm = .{ .type = void },
|
.is_bgm = .{ .type = void },
|
||||||
};
|
};
|
||||||
|
|
@ -40,12 +41,10 @@ fn init(
|
||||||
core: *mach.Core,
|
core: *mach.Core,
|
||||||
audio: *mach.Audio,
|
audio: *mach.Audio,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
app_audio_state_change: mach.Call(App, .audio_state_change),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// Configure the audio module to send our app's .audio_state_change event when an entity's sound
|
// Configure the audio module to send our app's .audio_state_change event when an entity's sound
|
||||||
// finishes playing.
|
// finishes playing.
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,10 @@ fn init(
|
||||||
sprite: *gfx.Sprite.Mod,
|
sprite: *gfx.Sprite.Mod,
|
||||||
sprite_pipeline: *gfx.SpritePipeline.Mod,
|
sprite_pipeline: *gfx.SpritePipeline.Mod,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// We can create entities, and set components on them. Note that components live in a module
|
// We can create entities, and set components on them. Note that components live in a module
|
||||||
// namespace, e.g. the `.mach_gfx_sprite` module could have a 3D `.location` component with a different
|
// namespace, e.g. the `.mach_gfx_sprite` module could have a 3D `.location` component with a different
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,10 @@ fn init(
|
||||||
text_pipeline: *gfx.TextPipeline.Mod,
|
text_pipeline: *gfx.TextPipeline.Mod,
|
||||||
text_style: *gfx.TextStyle.Mod,
|
text_style: *gfx.TextStyle.Mod,
|
||||||
app: *App,
|
app: *App,
|
||||||
app_tick: mach.Call(App, .tick),
|
app_mod: mach.Functions(App),
|
||||||
app_deinit: mach.Call(App, .deinit),
|
|
||||||
) !void {
|
) !void {
|
||||||
core.on_tick = app_tick.id;
|
core.on_tick = app_mod.id.tick;
|
||||||
core.on_exit = app_deinit.id;
|
core.on_exit = app_mod.id.deinit;
|
||||||
|
|
||||||
// TODO: a better way to initialize entities with default values
|
// TODO: a better way to initialize entities with default values
|
||||||
// TODO(text): ability to specify other style options (custom font name, font color, italic/bold, etc.)
|
// TODO(text): ability to specify other style options (custom font name, font color, italic/bold, etc.)
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ const sysaudio = mach.sysaudio;
|
||||||
|
|
||||||
pub const Opus = @import("mach-opus");
|
pub const Opus = @import("mach-opus");
|
||||||
|
|
||||||
pub const name = .mach_audio;
|
pub const mach_module = .mach_audio;
|
||||||
pub const Mod = mach.Mod(@This());
|
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.samples = .{ .type = []const f32 },
|
.samples = .{ .type = []const f32 },
|
||||||
.channels = .{ .type = u8 },
|
.channels = .{ .type = u8 },
|
||||||
|
|
@ -22,7 +22,7 @@ pub const systems = .{
|
||||||
.audio_tick = .{ .handler = audioTick },
|
.audio_tick = .{ .handler = audioTick },
|
||||||
};
|
};
|
||||||
|
|
||||||
const log = std.log.scoped(name);
|
const log = std.log.scoped(mach_module);
|
||||||
|
|
||||||
// The number of milliseconds worth of audio to render ahead of time. The lower this number is, the
|
// The number of milliseconds worth of audio to render ahead of time. The lower this number is, the
|
||||||
// less latency there is in playing new audio. The higher this number is, the less chance there is
|
// less latency there is in playing new audio. The higher this number is, the less chance there is
|
||||||
|
|
|
||||||
30
src/Core.zig
30
src/Core.zig
|
|
@ -233,17 +233,17 @@ pub fn init(core: *Core) !void {
|
||||||
try core.input.start();
|
try core.input.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(core: *Core, present_frame: mach.Call(Core, .present_frame), runner: mach.Runner) void {
|
pub fn tick(core: *Core, core_mod: mach.Functions(Core)) void {
|
||||||
runner.run(core.on_tick.?);
|
core_mod.run(core.on_tick.?);
|
||||||
runner.run(present_frame.id);
|
core_mod.call(.presentFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(core: *Core, present_frame: mach.Call(Core, .presentFrame), runner: mach.Runner) !void {
|
pub fn main(core: *Core, core_mod: mach.Functions(Core)) !void {
|
||||||
if (core.on_tick == null) @panic("core.on_tick callback must be set");
|
if (core.on_tick == null) @panic("core.on_tick callback must be set");
|
||||||
if (core.on_exit == null) @panic("core.on_exit callback must be set");
|
if (core.on_exit == null) @panic("core.on_exit callback must be set");
|
||||||
|
|
||||||
runner.run(core.on_tick.?);
|
core_mod.run(core.on_tick.?);
|
||||||
runner.run(present_frame.id);
|
core_mod.call(.presentFrame);
|
||||||
|
|
||||||
// If the user doesn't want mach.Core to take control of the main loop, we bail out - the next
|
// If the user doesn't want mach.Core to take control of the main loop, we bail out - the next
|
||||||
// app tick is already scheduled to run in the future and they'll .present_frame to return
|
// app tick is already scheduled to run in the future and they'll .present_frame to return
|
||||||
|
|
@ -259,8 +259,8 @@ pub fn main(core: *Core, present_frame: mach.Call(Core, .presentFrame), runner:
|
||||||
// The user wants mach.Core to take control of the main loop.
|
// The user wants mach.Core to take control of the main loop.
|
||||||
if (supports_non_blocking) {
|
if (supports_non_blocking) {
|
||||||
while (core.state().state != .exited) {
|
while (core.state().state != .exited) {
|
||||||
runner.run(core.on_tick.?);
|
core_mod.run(core.on_tick.?);
|
||||||
runner.run(present_frame.id);
|
core_mod.call(.presentFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't return, because Platform.run wouldn't either (marked noreturn due to underlying
|
// Don't return, because Platform.run wouldn't either (marked noreturn due to underlying
|
||||||
|
|
@ -268,7 +268,7 @@ pub fn main(core: *Core, present_frame: mach.Call(Core, .presentFrame), runner:
|
||||||
std.process.exit(0);
|
std.process.exit(0);
|
||||||
} else {
|
} else {
|
||||||
// Platform drives the main loop.
|
// Platform drives the main loop.
|
||||||
Platform.run(platform_update_callback, .{ core, present_frame.id, runner });
|
Platform.run(platform_update_callback, .{ core, core_mod });
|
||||||
|
|
||||||
// Platform.run should be marked noreturn, so this shouldn't ever run. But just in case we
|
// Platform.run should be marked noreturn, so this shouldn't ever run. But just in case we
|
||||||
// accidentally introduce a different Platform.run in the future, we put an exit here for
|
// accidentally introduce a different Platform.run in the future, we put an exit here for
|
||||||
|
|
@ -277,9 +277,9 @@ pub fn main(core: *Core, present_frame: mach.Call(Core, .presentFrame), runner:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn platform_update_callback(core: *Core, present_frame: mach.FunctionID, runner: mach.Runner) !bool {
|
fn platform_update_callback(core: *Core, core_mod: mach.Functions(Core)) !bool {
|
||||||
runner.run(core.on_tick.?);
|
core_mod.run(core.on_tick.?);
|
||||||
runner.run(present_frame);
|
core_mod.call(.presentFrame);
|
||||||
|
|
||||||
return core.state != .exited;
|
return core.state != .exited;
|
||||||
}
|
}
|
||||||
|
|
@ -563,7 +563,7 @@ pub fn mousePosition(core: *@This()) Position {
|
||||||
// return core.platform.nativeWindowWin32();
|
// return core.platform.nativeWindowWin32();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn presentFrame(core: *Core, core_deinit: mach.Call(Core, .deinit), runner: mach.Runner) !void {
|
pub fn presentFrame(core: *Core, core_mod: mach.Functions(Core)) !void {
|
||||||
// TODO(object)(window-title)
|
// TODO(object)(window-title)
|
||||||
// // Update windows title
|
// // Update windows title
|
||||||
// var num_windows: usize = 0;
|
// var num_windows: usize = 0;
|
||||||
|
|
@ -622,8 +622,8 @@ pub fn presentFrame(core: *Core, core_deinit: mach.Call(Core, .deinit), runner:
|
||||||
.running => {},
|
.running => {},
|
||||||
.exiting => {
|
.exiting => {
|
||||||
core.state = .deinitializing;
|
core.state = .deinitializing;
|
||||||
runner.run(core.on_exit.?);
|
core_mod.run(core.on_exit.?);
|
||||||
runner.run(core_deinit.id);
|
core_mod.call(.deinit);
|
||||||
},
|
},
|
||||||
.deinitializing => {},
|
.deinitializing => {},
|
||||||
.exited => @panic("application not running"),
|
.exited => @panic("application not running"),
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ const Vec3 = math.Vec3;
|
||||||
const Mat3x3 = math.Mat3x3;
|
const Mat3x3 = math.Mat3x3;
|
||||||
const Mat4x4 = math.Mat4x4;
|
const Mat4x4 = math.Mat4x4;
|
||||||
|
|
||||||
pub const name = .mach_gfx_sprite;
|
pub const mach_module = .mach_gfx_sprite;
|
||||||
pub const Mod = mach.Mod(@This());
|
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.transform = .{ .type = Mat4x4, .description =
|
.transform = .{ .type = Mat4x4, .description =
|
||||||
\\ The sprite model transformation matrix. A sprite is measured in pixel units, starting from
|
\\ The sprite model transformation matrix. A sprite is measured in pixel units, starting from
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ const mach = @import("../main.zig");
|
||||||
const gpu = mach.gpu;
|
const gpu = mach.gpu;
|
||||||
const math = mach.math;
|
const math = mach.math;
|
||||||
|
|
||||||
pub const name = .mach_gfx_sprite_pipeline;
|
pub const mach_module = .mach_gfx_sprite_pipeline;
|
||||||
pub const Mod = mach.Mod(@This());
|
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.texture = .{ .type = *gpu.Texture, .description =
|
.texture = .{ .type = *gpu.Texture, .description =
|
||||||
\\ Texture to use when rendering. The default shader can handle only one texture input.
|
\\ Texture to use when rendering. The default shader can handle only one texture input.
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ const Mat4x4 = math.Mat4x4;
|
||||||
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
|
||||||
pub const name = .mach_gfx_text;
|
pub const mach_module = .mach_gfx_text;
|
||||||
pub const Mod = mach.Mod(@This());
|
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.transform = .{ .type = Mat4x4, .description =
|
.transform = .{ .type = Mat4x4, .description =
|
||||||
\\ The text model transformation matrix. Text is measured in pixel units, starting from
|
\\ The text model transformation matrix. Text is measured in pixel units, starting from
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ const gfx = mach.gfx;
|
||||||
const gpu = mach.gpu;
|
const gpu = mach.gpu;
|
||||||
const math = mach.math;
|
const math = mach.math;
|
||||||
|
|
||||||
pub const name = .mach_gfx_text_pipeline;
|
pub const mach_module = .mach_gfx_text_pipeline;
|
||||||
pub const Mod = mach.Mod(@This());
|
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
.is_pipeline = .{ .type = void, .description =
|
.is_pipeline = .{ .type = void, .description =
|
||||||
\\ Tag to indicate an entity represents a text pipeline.
|
\\ Tag to indicate an entity represents a text pipeline.
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
const mach = @import("../main.zig");
|
const mach = @import("../main.zig");
|
||||||
const math = mach.math;
|
const math = mach.math;
|
||||||
|
|
||||||
pub const name = .mach_gfx_text_style;
|
pub const mach_module = .mach_gfx_text_style;
|
||||||
pub const Mod = mach.Mod(@This());
|
|
||||||
|
|
||||||
|
// TODO(object)
|
||||||
pub const components = .{
|
pub const components = .{
|
||||||
// // TODO: ship a default font
|
// // TODO: ship a default font
|
||||||
// .font_name = .{ .type = []const u8, .description =
|
// .font_name = .{ .type = []const u8, .description =
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,7 @@ pub const Modules = @import("module.zig").Modules;
|
||||||
pub const ModuleID = @import("module.zig").ModuleID;
|
pub const ModuleID = @import("module.zig").ModuleID;
|
||||||
pub const ModuleFunctionID = @import("module.zig").ModuleFunctionID;
|
pub const ModuleFunctionID = @import("module.zig").ModuleFunctionID;
|
||||||
pub const FunctionID = @import("module.zig").FunctionID;
|
pub const FunctionID = @import("module.zig").FunctionID;
|
||||||
pub const Call = @import("module.zig").Call;
|
pub const Functions = @import("module.zig").Functions;
|
||||||
pub const Runner = @import("module.zig").Runner;
|
|
||||||
|
|
||||||
pub const ObjectID = u32;
|
pub const ObjectID = u32;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,69 @@ pub const ModuleFunctionID = u16;
|
||||||
/// Unique identifier for a function within a module, including those only known at runtime.
|
/// Unique identifier for a function within a module, including those only known at runtime.
|
||||||
pub const FunctionID = struct { module_id: ModuleID, fn_id: ModuleFunctionID };
|
pub const FunctionID = struct { module_id: ModuleID, fn_id: ModuleFunctionID };
|
||||||
|
|
||||||
pub fn Call(module_tag_or_type: anytype, fn_name_tag: anytype) type {
|
pub fn Mod(comptime M: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
pub const IsMachCall = void;
|
pub const IsMachMod = void;
|
||||||
|
|
||||||
pub const module_name = module_tag_or_type;
|
pub const module_name = M.mach_module;
|
||||||
pub const fn_name = fn_name_tag;
|
pub const Module = M;
|
||||||
|
|
||||||
id: FunctionID,
|
id: ModFunctionIDs(M),
|
||||||
};
|
_ctx: *anyopaque,
|
||||||
}
|
|
||||||
|
|
||||||
pub const Runner = struct {
|
|
||||||
pub const IsMachRunner = void;
|
|
||||||
|
|
||||||
ctx: *anyopaque,
|
|
||||||
_run: *const fn (ctx: *anyopaque, fn_id: FunctionID) void,
|
_run: *const fn (ctx: *anyopaque, fn_id: FunctionID) void,
|
||||||
|
|
||||||
pub fn run(r: *const @This(), fn_id: FunctionID) void {
|
pub fn run(r: *const @This(), fn_id: FunctionID) void {
|
||||||
r._run(r.ctx, fn_id);
|
r._run(r._ctx, fn_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(r: *const @This(), comptime f: ModuleFunctionName2(M)) void {
|
||||||
|
const fn_id = @field(r.id, @tagName(f));
|
||||||
|
r.run(fn_id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ModFunctionIDs(comptime Module: type) type {
|
||||||
|
var fields: []const std.builtin.Type.StructField = &[0]std.builtin.Type.StructField{};
|
||||||
|
for (Module.mach_systems) |fn_name| {
|
||||||
|
fields = fields ++ [_]std.builtin.Type.StructField{.{
|
||||||
|
.name = @tagName(fn_name),
|
||||||
|
.type = FunctionID,
|
||||||
|
.default_value = null,
|
||||||
|
.is_comptime = false,
|
||||||
|
.alignment = @alignOf(FunctionID),
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
return @Type(.{
|
||||||
|
.Struct = .{
|
||||||
|
.layout = .auto,
|
||||||
|
.is_tuple = false,
|
||||||
|
.fields = fields,
|
||||||
|
.decls = &[_]std.builtin.Type.Declaration{},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enum describing all declarations for a given comptime-known module.
|
||||||
|
// TODO: unify with ModuleFunctionName
|
||||||
|
fn ModuleFunctionName2(comptime M: type) type {
|
||||||
|
validate(M);
|
||||||
|
var enum_fields: []const std.builtin.Type.EnumField = &[0]std.builtin.Type.EnumField{};
|
||||||
|
var i: u32 = 0;
|
||||||
|
inline for (M.mach_systems) |fn_tag| {
|
||||||
|
// TODO: verify decls are Fn or mach.schedule() decl
|
||||||
|
enum_fields = enum_fields ++ [_]std.builtin.Type.EnumField{.{ .name = @tagName(fn_tag), .value = i }};
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
return @Type(.{
|
||||||
|
.Enum = .{
|
||||||
|
.tag_type = if (enum_fields.len > 0) std.math.IntFittingRange(0, enum_fields.len - 1) else u0,
|
||||||
|
.fields = enum_fields,
|
||||||
|
.decls = &[_]std.builtin.Type.Declaration{},
|
||||||
|
.is_exhaustive = true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn Modules(module_lists: anytype) type {
|
pub fn Modules(module_lists: anytype) type {
|
||||||
inline for (moduleTuple(module_lists)) |module| {
|
inline for (moduleTuple(module_lists)) |module| {
|
||||||
|
|
@ -147,16 +189,11 @@ pub fn Modules(module_lists: anytype) type {
|
||||||
@field(args, arg.name) = &@field(m.mods, @tagName(std.meta.Child(arg.type).mach_module));
|
@field(args, arg.name) = &@field(m.mods, @tagName(std.meta.Child(arg.type).mach_module));
|
||||||
continue :outer;
|
continue :outer;
|
||||||
}
|
}
|
||||||
if (@typeInfo(arg.type) == .Struct and @hasDecl(arg.type, "IsMachCall")) {
|
if (@typeInfo(arg.type) == .Struct and @hasDecl(arg.type, "IsMachMod")) {
|
||||||
const machCall = arg.type;
|
const M = arg.type.Module;
|
||||||
@field(args, arg.name) = .{
|
var mv: Mod(M) = .{
|
||||||
.id = Module(@field(machCall, "module_name")).getFunction(@field(machCall, "fn_name")),
|
.id = undefined,
|
||||||
};
|
._ctx = m.modules,
|
||||||
continue :outer;
|
|
||||||
}
|
|
||||||
if (@typeInfo(arg.type) == .Struct and @hasDecl(arg.type, "IsMachRunner")) {
|
|
||||||
@field(args, arg.name) = Runner{
|
|
||||||
.ctx = m.modules,
|
|
||||||
._run = (struct {
|
._run = (struct {
|
||||||
pub fn run(ctx: *anyopaque, fn_id: FunctionID) void {
|
pub fn run(ctx: *anyopaque, fn_id: FunctionID) void {
|
||||||
const modules2: *Modules(module_lists) = @ptrCast(@alignCast(ctx));
|
const modules2: *Modules(module_lists) = @ptrCast(@alignCast(ctx));
|
||||||
|
|
@ -164,6 +201,10 @@ pub fn Modules(module_lists: anytype) type {
|
||||||
}
|
}
|
||||||
}).run,
|
}).run,
|
||||||
};
|
};
|
||||||
|
inline for (M.mach_systems) |m_fn_name| {
|
||||||
|
@field(mv.id, @tagName(m_fn_name)) = Module(M).getFunction(m_fn_name);
|
||||||
|
}
|
||||||
|
@field(args, arg.name) = mv;
|
||||||
continue :outer;
|
continue :outer;
|
||||||
}
|
}
|
||||||
@compileError("mach: function " ++ debug_name ++ " has an invalid argument(" ++ arg.name ++ ") type: " ++ @typeName(arg.type));
|
@compileError("mach: function " ++ debug_name ++ " has an invalid argument(" ++ arg.name ++ ") type: " ++ @typeName(arg.type));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue