dlangui.core.signals

This module contains definition of signals / listeners.

Similar to std.signals.

Unlike std.signals, supports any types of delegates, and as well interfaces with single method.

Unlike std.signals, can support return types for slots.

Caution: unlike std.signals, does not disconnect signal from slots belonging to destroyed objects.

Listener here stand for holder of single delegate (slot).

Signal is the same but supports multiple slots.

Listener has smaller memory footprint, but allows only single slot.

More...

Members

Structs

Listener
struct Listener(T1)

Single listener; parameter is interface with single method

Listener
struct Listener(RETURN_T, T1...)

Single listener; implicitly specified return and parameter types

Signal
struct Signal(T1)

Multiple listeners; implicitly specified return and parameter types

Signal
struct Signal(RETURN_T, T1...)

Multiple listeners; implicitly specified return and parameter types

Detailed Description

Can be declared either using list of result value and argument types, or by interface name with single method.

Synopsis:

1 import dlangui.core.signals;
2 
3 interface SomeInterface {
4     bool someMethod(string s, int n);
5 }
6 class Foo : SomeInterface {
7     override bool someMethod(string s, int n) {
8         writeln("someMethod called ", s, ", ", n);
9         return n > 10; // can return value
10     }
11 }
12 
13 // Listener! can hold arbitrary number of connected slots
14 
15 // declare using list of return value and parameter types
16 Listener!(bool, string, n) signal1;
17 
18 Foo f = new Foo();
19 // when signal is defined as type list, you can use delegate
20 signal1 = bool delegate(string s, int n) { writeln("inside delegate - ", s, n); return false; }
21 // or method reference
22 signal1 = &f.someMethod;
23 
24 // declare using interface with single method
25 Listener!SomeInterface signal2;
26 // you still can use any delegate
27 signal2 = bool delegate(string s, int n) { writeln("inside delegate - ", s, n); return false; }
28 // but for class method which overrides interface method, you can use simple syntax
29 signal2 = f; // it will automatically take &f.someMethod
30 
31 
32 // call listener(s) either by opcall or explicit emit
33 signal1("text", 1);
34 signal1.emit("text", 2);
35 signal2.emit("text", 3);
36 
37 // check if any slit is connected
38 if (signal1.assigned)
39     writeln("has listeners");
40 
41 // Signal! can hold arbitrary number of connected slots
42 
43 // declare using list of return value and parameter types
44 Signal!(bool, string, n) signal3;
45 
46 // add listeners via connect call
47 signal3.connect(bool delegate(string, int) { return false; });
48 // or via ~= operator
49 signal3 ~= bool delegate(string, int) { return false; };
50 
51 // declare using interface with single method
52 Signal!SomeInterface signal4;
53 
54 // you can connect several slots to signal
55 signal4 ~= f;
56 signal4 ~= bool delegate(string, int) { return true; }
57 
58 // calling of listeners of Signal! is similar to Listener!
59 // using opCall
60 bool res = signal4("blah", 5);
61 // call listeners using emit
62 bool res = signal4.emit("blah", 5);
63 
64 // you can disconnect individual slots
65 // using disconnect()
66 signal4.disconnect(f);
67 // or -= operator
68 signal4 -= f;

Meta

License

Boost License 1.0

Authors

Vadim Lopatin, coolreader.org@gmail.com