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

Reply via email to