Files
6soz/src/contract/system.zig
T

133 lines
3.2 KiB
Zig

const video = @import("video.zig");
const audio = @import("audio.zig");
const input = @import("input.zig");
const storage = @import("storage.zig");
pub const Spec = struct {
name: []const u8,
video_outputs: []const video.VideoOutputSpec = &.{},
audio_outputs: []const audio.StreamSpec = &.{},
audio_inputs: []const audio.StreamSpec = &.{},
input_devices: []const input.DeviceSpec = &.{},
storage_devices: []const storage.Spec = &.{},
};
pub fn validate(comptime System: type) void {
comptime {
if (!@hasDecl(System, "spec")) {
@compileError(
"System must expose `pub const spec: contract.SystemSpec`",
);
}
if (@TypeOf(System.spec) != Spec) {
@compileError(
"`System.spec` must have type contract.SystemSpec",
);
}
requireFunction(
System,
"reset",
fn (*System) void,
);
requireFunction(
System,
"runFrame",
fn (*System) void,
);
if (System.spec.video_outputs.len != 0) {
requireFunction(
System,
"videoFrame",
fn (*const System, usize) video.VideoFrame,
);
}
if (System.spec.audio_outputs.len != 0) {
requireFunction(
System,
"audioBuffer",
fn (*const System, usize) audio.Buffer,
);
}
if (System.spec.audio_inputs.len != 0) {
requireFunction(
System,
"submitAudioInput",
fn (*System, usize, audio.Buffer) void,
);
}
if (System.spec.input_devices.len != 0) {
requireFunction(
System,
"setInput",
fn (*System, usize, input.DeviceInput) void,
);
}
var has_haptics = false;
for (System.spec.input_devices) |device| {
if (device.haptic_count != 0) {
has_haptics = true;
break;
}
}
if (has_haptics) {
requireFunction(
System,
"deviceFeedback",
fn (*const System, usize) input.DeviceFeedback,
);
}
if (System.spec.storage_devices.len != 0) {
requireFunction(
System,
"storageView",
fn (*const System, usize) storage.View,
);
requireFunction(
System,
"loadStorage",
fn (
*System,
usize,
[]const u8,
) storage.LoadError!void,
);
}
}
}
fn requireFunction(
comptime System: type,
comptime name: []const u8,
comptime Expected: type,
) void {
if (!@hasDecl(System, name)) {
@compileError(
"System must implement `" ++ name ++ "`",
);
}
const Actual = @TypeOf(@field(System, name));
if (Actual != Expected) {
@compileError(
"`" ++ name ++ "` has an invalid signature",
);
}
}