digitalmars.D - More flexible Signals/Slots
- Bill Baxter (39/39) Nov 15 2006 Layering on top of std.signal, I've made a FlexSignal object which has
Layering on top of std.signal, I've made a FlexSignal object which has calling rules for slots that are as flexible as normal function calls. (std.signal will only accept delegates that have the _exact_ same type signature as the signal expects, including void return type). In other words if it is legal to use this 'emit' command with your signal: sig.emit(a,b,c,d); and it is legal to call your slot directly like this some_slot(a,b,c,d); then FlexSignal allows you to connect to it: sig.connect(&some_slot); Even further, FlexSignal also lets you connect anything that could be called in one of these ways: some_slot3(a,b,c); some_slot2(a,b); some_slot1(a); some_slot0(); It's a little heavier weight than std.signals.Signal because it has to create a 'thunk' for every slot added that doesn't match the signal's slot_t signature exactly. But it makes for a much more flexible signal/slot mechanism. This wouldn't be possible to do without the great new tuple fixes in DMD 0.174! Issues: * AFAIK, there is no way to tell the difference between a class delegate, and a struct delegate, and a delegate literal. Given that DMD can only handle class delegates, there's no way to decide currently if thunking is really necessary or not. The check 'is(slot_t==give_slot_t)' will succeed regardless of the underlying delegate.ptr type. Because of this, for now FlexSignal wraps every delegate that comes in, regardless of whether the type signature matches. Future/Exercise for the reader: * It would be nice to be able to add a slot that e.g. only wants the 2nd parameter emitted by the signal. // assume we have something we can call as 'some_slot_b(b)' sig.fconnect(some_slot_b, 1); // only pass argument 1 or only wants first and third args: // assume we have something we can call as 'some_slot_ac(a,c)' sig.fconnect(some_slot_ac, 0,2); // only pass arguments 0 and 2 --bb
Nov 15 2006