48 lines
1.4 KiB
Zig
48 lines
1.4 KiB
Zig
const std = @import("std");
|
|
const Sink = @import("sink.zig").Sink;
|
|
const Signal = @import("signal.zig").Signal;
|
|
const utils = @import("../ecs/utils.zig");
|
|
|
|
pub const Dispatcher = struct {
|
|
signals: std.AutoHashMap(u32, usize),
|
|
allocator: std.mem.Allocator,
|
|
|
|
pub fn init(allocator: std.mem.Allocator) Dispatcher {
|
|
return Dispatcher{
|
|
.signals = std.AutoHashMap(u32, usize).init(allocator),
|
|
.allocator = allocator,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *Dispatcher) void {
|
|
var iter = self.signals.iterator();
|
|
while (iter.next()) |ptr| {
|
|
// HACK: we dont know the Type here but we need to call deinit
|
|
var signal = @as(*Signal(void), @ptrFromInt(ptr.value_ptr.*));
|
|
signal.deinit();
|
|
}
|
|
|
|
self.signals.deinit();
|
|
}
|
|
|
|
fn assure(self: *Dispatcher, comptime T: type) *Signal(T) {
|
|
var type_id = utils.typeId(T);
|
|
if (self.signals.get(type_id)) |value| {
|
|
return @as(*Signal(T), @ptrFromInt(value));
|
|
}
|
|
|
|
var signal = Signal(T).create(self.allocator);
|
|
var signal_ptr = @intFromPtr(signal);
|
|
_ = self.signals.put(type_id, signal_ptr) catch unreachable;
|
|
return signal;
|
|
}
|
|
|
|
pub fn sink(self: *Dispatcher, comptime T: type) Sink(T) {
|
|
return self.assure(T).sink();
|
|
}
|
|
|
|
pub fn trigger(self: *Dispatcher, comptime T: type, value: T) void {
|
|
self.assure(T).publish(value);
|
|
}
|
|
};
|