Signals far from Slots
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon May 5 15:19:48 PDT 2014
On 05/04/2014 10:57 AM, Jim Hewes wrote:
> Is there a good way to connect signals and slots when the objects are
> far apart? All tutorials for signals and slots show the objects being
> readily accessible by the main() function. But what if they're not? Is
> there an elegant design?
>
> For example, here's a typical minimal demo:
>
> ---------------------------------------------------------
> class Foo
> {
> void Listen()
> {
> writeln("Foo: I hear you!");
> }
> }
>
> class Bar
> {
> mixin Signal!() barSignal;
> void SaySomething()
> { emit(); }
> }
>
> int main(string[] argv)
> {
> Foo f = new Foo();
> Bar b = new Bar();
>
> b.barSignal.connect(&f.Listen);
> b.SaySomething();
> return 0;
> }
> ---------------------------------------------------------------
>
> The main() function is a kind of controller that connects up the
> components. But let's say main() doesn't have access to Bar because it's
> behind a layer:
>
> ------------------------------------------------------------------
>
> class BarContainer
> {
> this() { b = new Bar(); }
>
> void SetBarSignalHandler(b.barSignal.slot_t dg)
> { b.barSignal.connect(dg); }
>
> private Bar b;
> };
>
> int main(string[] argv)
> {
> Foo f = new Foo();
> BarContainer bc = new BarContainer();
>
> bc.SetBarSignalHandler(&f.Listen);
> return 0;
> }
> ------------------------------------------------------------------
> This can get worse if there is also a FooContainer and objects get
> further away.
>
> My first thought is to pass the delegates through the layers, as in the
> SetBarSignalHandler() function in BarContainer. But this seems kind of
> ugly as all the layers need to know about the connection between the
> signaling object and the observer object. It would be nice if they
> didn't have to.
>
> Do you know any any cleaner way?
>
> Jim
As far as I understand, you have to expose a function on BarContainer
similar to SaySomething() (I named it SaySomething() as well :) ):
import std.stdio;
import std.signals;
class Foo
{
void Listen()
{
writeln("Foo: I hear you!");
}
}
class Bar
{
mixin Signal!() barSignal;
void SaySomething()
{ emit(); }
}
class BarContainer
{
this() { b = new Bar(); }
void SetBarSignalHandler(b.barSignal.slot_t dg)
{ b.barSignal.connect(dg); }
void SaySomething() // <== ADDED
{
b.emit();
}
private Bar b;
}
int main(string[] argv)
{
Foo f = new Foo();
BarContainer bc = new BarContainer();
bc.SetBarSignalHandler(&f.Listen);
bc.SaySomething(); // <== ADDED
return 0;
}
Ali
More information about the Digitalmars-d-learn
mailing list