Im­prove this page Quickly fork, edit on­line, and sub­mit a pull re­quest for this page. Re­quires a signed-in GitHub ac­count. This works well for small changes. If you'd like to make larger changes you may want to con­sider using local clone. Page wiki View or edit the com­mu­nity-main­tained wiki page as­so­ci­ated with this page.

std.​signals

Jump to: Signal slot_t emit connect disconnect

Sig­nals and Slots are an im­ple­men­ta­tion of the Ob­server Pat­tern. Es­sen­tially, when a Sig­nal is emit­ted, a list of con­nected Ob­servers (called slots) are called.

There have been sev­eral D im­ple­men­ta­tions of Sig­nals and Slots. This ver­sion makes use of sev­eral new fea­tures in D, which make using it sim­pler and less error prone. In par­tic­u­lar, it is no longer nec­es­sary to in­stru­ment the slots.

Ref­er­ences:
A Deeper Look at Sig­nals and Slots
Ob­server pat­tern
Wikipedia
Boost Sig­nals
Qt

There has been a great deal of dis­cus­sion in the D news­groups over this, and sev­eral im­ple­men­ta­tions:

sig­nal slots li­brary
Sig­nals and Slots in D
Dy­namic bind­ing -- Qt's Sig­nals and Slots vs Ob­jec­tive-C
Dis­sect­ing the SS
about har­mo­nia
An­other event han­dling mod­ule
Sug­ges­tion: sig­nal/slot mech­a­nism
Sig­nals and slots?
Sig­nals and slots ready for eval­u­a­tion
Sig­nals & Slots for Wal­ter
Sig­nal/Slot mech­a­nism?
Mod­ern Fea­tures?
Del­e­gates vs in­ter­faces
The im­por­tance of com­po­nent pro­gram­ming (prop­er­ties sig­nals and slots etc)
sig­nals and slots

BUGS:
Slots can only be del­e­gates formed from class ob­jects or in­ter­faces to class ob­jects. If a del­e­gate to some­thing else is passed to con­nect(), such as a struct mem­ber func­tion, a nested func­tion or a COM in­ter­face, un­de­fined be­hav­ior will re­sult.

Not safe for mul­ti­ple threads op­er­at­ing on the same sig­nals or slots.

Li­cense:
Boost Li­cense 1.0.

Au­thors:
Wal­ter Bright

Source:
std/sig­nals.d

tem­plate Sig­nal(T1...)
Mixin to cre­ate a sig­nal within a class ob­ject.

Dif­fer­ent sig­nals can be added to a class by nam­ing the mix­ins.

Ex­am­ple:
import std.signals;
import std.stdio;

class Observer
{   // our slot
    void watch(string msg, int i)
    {
        writefln("Observed msg '%s' and value %s", msg, i);
    }
}

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;
}

void main()
{
    Foo a = new Foo;
    Observer o = new Observer;

    a.value = 3;                // should not call o.watch()
    a.connect(&o.watch);        // o.watch is the slot
    a.value = 4;                // should call o.watch()
    a.disconnect(&o.watch);     // o.watch is no longer a slot
    a.value = 5;                // so should not call o.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()
}
which should print:
 Observed msg 'setting new value' and value 4
 Observed msg 'setting new value' and value 6
 

alias void del­e­gate(T1) slot_t;
A slot is im­ple­mented as a del­e­gate. The slot_t is the type of the del­e­gate. The del­e­gate must be to an in­stance of a class or an in­ter­face to a class in­stance. Del­e­gates to struct in­stances or nested func­tions must not be used as slots.

void emit(T1 i);
Call each of the con­nected slots, pass­ing the ar­gu­ment(s) i to them.

void con­nect(slot_t slot);
Add a slot to the list of slots to be called when emit() is called.

void dis­con­nect(slot_t slot);
Re­move a slot from the list of slots to be called when emit() is called.