allow inserts

master
Mike 5 years ago
parent 1234b801fd
commit 917ca5ffdc

@ -77,9 +77,6 @@ test "Signal/Sink" {
sink.connect(tester);
std.testing.expectEqual(@as(usize, 1), signal.size());
sink.connect(tester);
std.testing.expectEqual(@as(usize, 1), signal.size());
// bound listener
var thing = Thing{};
sink.connectBound(&thing, "tester");
@ -93,3 +90,16 @@ test "Signal/Sink" {
sink.disconnectBound(&thing);
std.testing.expectEqual(@as(usize, 0), signal.size());
}
test "Sink Before null" {
var signal = Signal(u32).init(std.testing.allocator);
defer signal.deinit();
var sink = signal.sink();
sink.connect(tester);
std.testing.expectEqual(@as(usize, 1), signal.size());
var thing = Thing{};
sink.before(null).connectBound(&thing, "tester");
std.testing.expectEqual(@as(usize, 2), signal.size());
}

@ -8,40 +8,108 @@ pub fn Sink(comptime Event: type) type {
return struct {
const Self = @This();
insert_index: usize,
/// 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{};
return Self{ .insert_index = owning_signal.calls.items.len };
}
pub fn before(self: Self, callback: ?fn (Event) void) Self {
if (callback) |cb| {
if (self.indexOf(cb)) |index| {
return Self{ .insert_index = index };
}
}
return self;
}
pub fn beforeBound(self: Self, ctx: var) Self {
if (@typeInfo(@TypeOf(ctx)) == .Pointer) {
if (self.indexOfBound(ctx)) |index| {
return Self{ .insert_index = index };
}
}
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;
std.debug.assert(self.indexOf(callback) == null);
_ = owning_signal.calls.insert(self.insert_index, 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;
std.debug.assert(self.indexOfBound(ctx) == null);
_ = owning_signal.calls.insert(self.insert_index, Delegate(Event).initBound(ctx, fn_name)) catch unreachable;
}
pub fn disconnect(self: Self, callback: fn (Event) void) void {
if (self.indexOf(callback)) |index| {
_ = owning_signal.calls.swapRemove(index);
}
}
pub fn disconnectBound(self: Self, ctx: var) void {
if (self.indexOfBound(ctx)) |index| {
_ = owning_signal.calls.swapRemove(index);
}
}
fn indexOf(self: Self, callback: fn (Event) void) ?usize {
for (owning_signal.calls.items) |call, i| {
if (call.containsFree(callback)) {
_ = owning_signal.calls.swapRemove(i);
break;
return i;
}
}
return null;
}
pub fn disconnectBound(self: Self, ctx: var) void {
fn indexOfBound(self: Self, ctx: var) ?usize {
for (owning_signal.calls.items) |call, i| {
if (call.containsBound(ctx)) {
_ = owning_signal.calls.swapRemove(i);
break;
return i;
}
}
return null;
}
};
}
fn tester(param: u32) void {
std.testing.expectEqual(@as(u32, 666), param);
}
const Thing = struct {
field: f32 = 0,
pub fn tester(self: *Thing, param: u32) void {
std.testing.expectEqual(@as(u32, 666), param);
}
};
test "Sink Before free" {
var signal = Signal(u32).init(std.testing.allocator);
defer signal.deinit();
signal.sink().connect(tester);
std.testing.expectEqual(signal.sink().indexOf(tester).?, 0);
var thing = Thing{};
signal.sink().before(tester).connectBound(&thing, "tester");
std.testing.expectEqual(signal.sink().indexOfBound(&thing).?, 0);
}
test "Sink Before bound" {
var signal = Signal(u32).init(std.testing.allocator);
defer signal.deinit();
var thing = Thing{};
signal.sink().connectBound(&thing, "tester");
std.testing.expectEqual(signal.sink().indexOfBound(&thing).?, 0);
signal.sink().beforeBound(&thing).connect(tester);
std.testing.expectEqual(signal.sink().indexOf(tester).?, 0);
}
Loading…
Cancel
Save