View source code
Display the source code in std/signals.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

Template std.signals.Signal

Mixin to create a signal within a class object.

template Signal(T1...) ;

Different signals can be added to a class by naming the mixins.

Contained Functions

NameDescription
connect Add a slot to the list of slots to be called when emit() is called.
disconnect Remove a slot from the list of slots to be called when emit() is called.
disconnectAll Disconnect all the slots.
emit Call each of the connected slots, passing the argument(s) i to them. Nested call will be ignored.

Contained Aliases

NameDescription
slot_t A slot is implemented as a delegate. The slot_t is the type of the delegate. The delegate must be to an instance of a class or an interface to a class instance. Delegates to struct instances or nested functions must not be used as slots. This applies even if the nested function does not access it's parent function variables.

Example

import std.signals;

int observedMessageCounter = 0;

class Observer
{   // our slot
    void watch(string msg, int value)
    {
        switch (observedMessageCounter++)
        {
            case 0:
                writeln(msg); // "setting new value"
                writeln(value); // 4
                break;
            case 1:
                writeln(msg); // "setting new value"
                writeln(value); // 6
                break;
            default:
                assert(0, "Unknown observation");
        }
    }
}

class Observer2
{   // our slot
    void watch(string msg, int value)
    {
    }
}

class Foo
{
    int value() { return _value; }

    int value(int v)
    {
        if (v != _value)
        {   _value = v;
            // call all the connected slots with the two parameters
            emit("setting new value", v);
        }
        return v;
    }

    // Mix in all the code we need to make Foo into a signal
    mixin Signal!(string, int);

  private :
    int _value;
}

Foo a = new Foo;
Observer o = new Observer;
auto o2 = new Observer2;
auto o3 = new Observer2;
auto o4 = new Observer2;
auto o5 = new Observer2;

a.value = 3;                // should not call o.watch()
a.connect(&o.watch);        // o.watch is the slot
a.connect(&o2.watch);
a.connect(&o3.watch);
a.connect(&o4.watch);
a.connect(&o5.watch);
a.value = 4;                // should call o.watch()
a.disconnect(&o.watch);     // o.watch is no longer a slot
a.disconnect(&o3.watch);
a.disconnect(&o5.watch);
a.disconnect(&o4.watch);
a.disconnect(&o2.watch);
a.value = 5;                // so should not call o.watch()
a.connect(&o2.watch);
a.connect(&o.watch);        // connect again
a.value = 6;                // should call o.watch()
destroy(o);                 // destroying o should automatically disconnect it
a.value = 7;                // should not call o.watch()

writeln(observedMessageCounter); // 2
}

// A function whose sole purpose is to get this module linked in
// so the unittest will run.
void linkin() { 

Authors

Walter Bright

License

Boost License 1.0.