luigi.signalobj
signalobj
.d - a few utilities for creating signal objects for more flexible
signals and slots.
Written by Bill Baxter, November 9, 2006.
This code is released to the public domain
- class
SignalObj
(T...);
- A simple object that wraps a std.signal. This allows creating signals at
global scope, returning them from functions, etc.
In terms of what can be connected, this has the same restrictions as
the std.signal.Signal mixin, namely the slot delegate signature must
match the signal's signature exactly.
- class
DelegateSlot
(T...);
- A wrapper for a delegate. This lets one use delegate literals
as a slot in some situations where they would cause access errors.
- struct
slot_key
;
- A simple opaque datatype which serves as a key for FlexSignal.fdisconnect.
The primary use is internal, for keeping a mapping between user slots
and their wrappers. However, they can also be used as a key to a delegate
literal for later disconnecting.
- class
FlexSignal
(T...);
-
FlexSignal
is a more flexible version of a signal object wrapper.
Using the connect/disconnect methods it is possible to connect the
signal to most any callable entity with a signature that is 'compatible'.
with the signal's signature.
Specifically one can connect
- functions and delegate literals.
- slots that return values (the return value is simply ignored by the signal)
- slots that take fewer parameters than the signal supplies
(trailing paramters from signal simply aren't passed to the slot).
- delegates with fewer arguments
than the signal supplies are allowed, and any argument which can
be implicitly converted by D is allowed as well.
- void
emit
(T v);
- Emit the signal with the given arguments.
- slot_t
connect_exact
(slot_t f);
- Connect a slot to the signal using a class delegate exactly
matching the signature of the signal.
Returns:
the slot passed in.
- slot_t
disconnect_exact
(slot_t f);
- Disconnect a slot from the signal using a class delegate exactly
matching the signature of the signal.
Returns:
the slot passed in.
- template
connect
(DT,int arg_offset = 0)
- A flexible version of
connect
. Works for delegates to classes
or structs, plain functions, delegate literals. Also works for
things with or without return values, and with fewer
arguments than the signal supplies.
So for example, an (int,char[]) FlexSignal can be connected to an
int funciton that returns a float.
Also it can convert compatible argument types, any thing that can
be implicitly converted at runtime is allowed.
So for example, the (int, char[]) FlexSigal can be connected to a
method taking a (double,char[]) because int is automatically
promoted to double.
Returns:
a slot key which can be used to disconnect the item
later. (You can also use the original slot to disconnect if you
have it.)
- slot_key
connect
(DT f);
- A flexible version of
connect
. Works for delegates to classes
or structs, plain functions, delegate literals. Also works for
things with or without return values, and with fewer
arguments than the signal supplies.
So for example, an (int,char[]) FlexSignal can be connected to an
int funciton that returns a float.
Also it can convert compatible argument types, any thing that can
be implicitly converted at runtime is allowed.
So for example, the (int, char[]) FlexSigal can be connected to a
method taking a (double,char[]) because int is automatically
promoted to double.
Returns:
a slot key which can be used to disconnect the item
later. (You can also use the original slot to disconnect if you
have it.)
- alias
opCatAssign
;
- Provides an alternate signal for connect() using the ~= operator.
This can allow for somewhat cleaner syntax when using delegate literals.
(One set of parentheses is eliminated)
For example:
theSignal ~= (Widget w, bool onoff) {
writefln(onoff?"checked!":"unchecked!");};
Versus
theSignal.connect( (Widget w, bool onoff) {
writefln(onoff?"checked!":"unchecked!");});
The downside is that it is not possible to specify template
arguments for ~= explicitly if needed.
- template
connect1st
(DT)
- Some simple wrappers for the most comment skipped argument
versions of connect. These work well with implicit instatiation.
- slot_key
connect1st
(DT f);
- Some simple wrappers for the most comment skipped argument
versions of connect. These work well with implicit instatiation.
- template
disconnect
(DT)
- Disconnect a slot of any type
- void
disconnect
(DT f);
- Disconnect a slot of any type
- template
SlotAdapter
(slot_t)
-
SlotAdapter
is a template that takes a signal's 'slot_t' delegate type.
It contains two functions, wrap() and adapt().
wrap() returns a slot_t delegate to object that wraps a passed in
delegate or function which may have a signature that differs from
'slot_t'. As long as the callable entity passed in has argument
types compatible with 'slot_t' then the operation should succeed. In
particular exact matching with slot_t's parameter types is not
necessary, any type implicitly convertable from the slot_t's argument
type is ok.
adapt() is the same as wrap(), except it will return the original
delegate without creating a wrapper if that delegate's matches the
slot_t exactly.
Usage:
auto wrapped =
SlotAdapter
!(Signals_SlotType).wrap(target_slot)
auto adapted =
SlotAdapter
!(Signals_SlotType).adapt(target_slot)
|