101 lines
3.5 KiB
Zig
101 lines
3.5 KiB
Zig
|
const std = @import("std");
|
||
|
const _registry = @import("registry.zig");
|
||
|
const _model = @import("model.zig");
|
||
|
const _dispatchers = @import("dispatchers.zig");
|
||
|
|
||
|
|
||
|
/// Type of dispatchers map.
|
||
|
pub const DispatchersMap = std.StaticStringMap(_dispatchers.Dispatcher);
|
||
|
|
||
|
/// Type of models dispatchers map.
|
||
|
pub const ModelsDispatchersMap = std.StaticStringMap(DispatchersMap);
|
||
|
|
||
|
/// Build dispatchers maps of all models from the dispatchers definition structure.
|
||
|
fn BuildModelsDispatchersMaps(comptime dispatchersDefinition: type) ModelsDispatchersMap {
|
||
|
return ModelsDispatchersMap.initComptime(comptime dispatchersKv: {
|
||
|
// Get all models dispatchers definition structures.
|
||
|
const modelsDispatchersDecls = std.meta.declarations(dispatchersDefinition);
|
||
|
|
||
|
// Initialize a new key-values array for all models.
|
||
|
var dispatchersKv: [modelsDispatchersDecls.len]struct{[]const u8, DispatchersMap} = undefined;
|
||
|
|
||
|
// Build all dispatchers maps and add them in the key-values array.
|
||
|
for (&dispatchersKv, modelsDispatchersDecls) |*dispatcherKv, modelDispatchersDecl| {
|
||
|
dispatcherKv.* = .{ modelDispatchersDecl.name, BuildDispatchersMap(modelDispatchersDecl.name, @field(dispatchersDefinition, modelDispatchersDecl.name)) };
|
||
|
}
|
||
|
|
||
|
// Return the new dispatchers maps key-values.
|
||
|
break :dispatchersKv dispatchersKv;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/// Build a dispatchers map for a model from its dispatchers definition structure.
|
||
|
fn BuildDispatchersMap(comptime modelName: []const u8, comptime dispatchersBuilders: type) DispatchersMap {
|
||
|
// Return the new dispatchers map.
|
||
|
return DispatchersMap.initComptime(comptime dispatchersKv: {
|
||
|
// Get all dispatchers declarations.
|
||
|
const dispatchersDecls = std.meta.declarations(dispatchersBuilders);
|
||
|
|
||
|
// Initialize a new key-values array for all dispatchers.
|
||
|
var dispatchersKv: [dispatchersDecls.len]struct{[]const u8, _dispatchers.Dispatcher} = undefined;
|
||
|
|
||
|
// Build all dispatchers and add them in the key-values array.
|
||
|
for (dispatchersKv[0..dispatchersDecls.len], dispatchersDecls) |*dispatcherKv, dispatcherDecl| {
|
||
|
dispatcherKv.* = .{ dispatcherDecl.name, @field(dispatchersBuilders, dispatcherDecl.name).build(modelName, dispatcherDecl.name) };
|
||
|
}
|
||
|
|
||
|
// Return the new dispatchers key-values.
|
||
|
break :dispatchersKv dispatchersKv;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
/// MQL API structure.
|
||
|
pub fn Api(
|
||
|
comptime registry: type,
|
||
|
comptime dispatchersDefinition: type,
|
||
|
) type {
|
||
|
// Build models dispatchers map.
|
||
|
const dispatchersMap = BuildModelsDispatchersMaps(dispatchersDefinition);
|
||
|
|
||
|
// Compute dispatchers array size.
|
||
|
const dispatchersArraySize = comptime dispatchersArraySize: {
|
||
|
var size = 0;
|
||
|
|
||
|
for (dispatchersMap.values()) |dispatchers| {
|
||
|
size += dispatchers.values().len;
|
||
|
}
|
||
|
|
||
|
break :dispatchersArraySize size;
|
||
|
};
|
||
|
// Build dispatchers array.
|
||
|
const dispatchersArray = comptime dispatchersArray: {
|
||
|
var dispatchersArray: [dispatchersArraySize]_dispatchers.Dispatcher = undefined;
|
||
|
var dispatchersArrayIndex = 0;
|
||
|
|
||
|
for (dispatchersMap.values()) |dispatchers| {
|
||
|
for (dispatchers.values()) |dispatcher| {
|
||
|
dispatchersArray[dispatchersArrayIndex] = dispatcher;
|
||
|
dispatchersArrayIndex += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break :dispatchersArray dispatchersArray;
|
||
|
};
|
||
|
|
||
|
return struct {
|
||
|
pub const Registry = registry;
|
||
|
pub const dispatchers = dispatchersMap;
|
||
|
|
||
|
/// Get model name from its provided instance.
|
||
|
pub fn getModelName(comptime model: _model.Model) []const u8 {
|
||
|
return Registry.getModelName(model);
|
||
|
}
|
||
|
|
||
|
/// Get a list of all declared dispatchers.
|
||
|
pub fn getDispatchers() []const _dispatchers.Dispatcher {
|
||
|
return dispatchersArray[0..dispatchersArraySize];
|
||
|
}
|
||
|
};
|
||
|
}
|