2020-05-31 21:28:29 -07:00
|
|
|
const std = @import("std");
|
|
|
|
const Sink = @import("sink.zig").Sink;
|
|
|
|
const Signal = @import("signal.zig").Signal;
|
2020-06-04 13:37:51 -07:00
|
|
|
const utils = @import("../ecs/utils.zig");
|
2020-05-31 21:28:29 -07:00
|
|
|
|
|
|
|
pub const Dispatcher = struct {
|
2020-06-04 13:37:51 -07:00
|
|
|
signals: std.AutoHashMap(u32, usize),
|
2020-05-31 21:28:29 -07:00
|
|
|
allocator: *std.mem.Allocator,
|
|
|
|
|
|
|
|
pub fn init(allocator: *std.mem.Allocator) Dispatcher {
|
2020-06-04 13:37:51 -07:00
|
|
|
return Dispatcher{
|
|
|
|
.signals = std.AutoHashMap(u32, usize).init(allocator),
|
2020-05-31 21:28:29 -07:00
|
|
|
.allocator = allocator,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-08-05 22:37:17 +02:00
|
|
|
pub fn deinit(self: *Dispatcher) void {
|
2020-12-04 12:48:15 -08:00
|
|
|
var iter = self.signals.iterator();
|
|
|
|
while (iter.next()) |ptr| {
|
2020-05-31 21:28:29 -07:00
|
|
|
// HACK: we dont know the Type here but we need to call deinit
|
2021-06-29 22:26:23 -06:00
|
|
|
var signal = @intToPtr(*Signal(void), ptr.value_ptr.*);
|
2020-05-31 21:28:29 -07:00
|
|
|
signal.deinit();
|
|
|
|
}
|
|
|
|
|
|
|
|
self.signals.deinit();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn assure(self: *Dispatcher, comptime T: type) *Signal(T) {
|
2020-06-04 13:37:51 -07:00
|
|
|
var type_id = utils.typeId(T);
|
2020-08-05 22:37:17 +02:00
|
|
|
if (self.signals.get(type_id)) |value| {
|
|
|
|
return @intToPtr(*Signal(T), value);
|
2020-05-31 21:28:29 -07:00
|
|
|
}
|
|
|
|
|
2020-06-04 13:37:51 -07:00
|
|
|
var signal = Signal(T).create(self.allocator);
|
|
|
|
var signal_ptr = @ptrToInt(signal);
|
|
|
|
_ = self.signals.put(type_id, signal_ptr) catch unreachable;
|
|
|
|
return signal;
|
2020-05-31 21:28:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
};
|