48 lines
1.7 KiB
Zig
48 lines
1.7 KiB
Zig
|
const std = @import("std");
|
||
|
const Signal = @import("signal.zig").Signal;
|
||
|
const Delegate = @import("delegate.zig").Delegate;
|
||
|
|
||
|
/// helper used to connect and disconnect listeners on the fly from a Signal. Listeners are wrapped in Delegates
|
||
|
/// and can be either free functions or functions bound to a struct.
|
||
|
pub fn Sink(comptime Event: type) type {
|
||
|
return struct {
|
||
|
const Self = @This();
|
||
|
|
||
|
/// the Signal this Sink is temporarily wrapping
|
||
|
var owning_signal: *Signal(Event) = undefined;
|
||
|
|
||
|
pub fn init(signal: *Signal(Event)) Self {
|
||
|
owning_signal = signal;
|
||
|
return Self{};
|
||
|
}
|
||
|
|
||
|
pub fn connect(self: Self, callback: fn (Event) void) void {
|
||
|
self.disconnect(callback);
|
||
|
_ = owning_signal.calls.append(Delegate(Event).initFree(callback)) catch unreachable;
|
||
|
}
|
||
|
|
||
|
pub fn connectBound(self: Self, ctx: var, comptime fn_name: []const u8) void {
|
||
|
self.disconnectBound(ctx);
|
||
|
_ = owning_signal.calls.append(Delegate(Event).initBound(ctx, fn_name)) catch unreachable;
|
||
|
}
|
||
|
|
||
|
pub fn disconnect(self: Self, callback: fn (Event) void) void {
|
||
|
for (owning_signal.calls.items) |call, i| {
|
||
|
if (call.containsFree(callback)) {
|
||
|
_ = owning_signal.calls.swapRemove(i);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn disconnectBound(self: Self, ctx: var) void {
|
||
|
for (owning_signal.calls.items) |call, i| {
|
||
|
if (call.containsBound(ctx)) {
|
||
|
_ = owning_signal.calls.swapRemove(i);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|