| 3 | | I will add some of the information here soon. |
| | 3 | The Signal Network library aims to facilitate the |
| | 4 | implementation and interconnection of objects into signal networks using Boost.Signals. |
| | 5 | To understand the concept of signals (data generators / senders) and slots (data consumers / receivers), |
| | 6 | please see the Boost.Signals [http://www.boost.org/doc/html/signals.html documentation] |
| | 7 | and the associated [http://www.boost.org/doc/html/signals/tutorial.html tutorial]. |
| | 8 | |
| | 9 | This is a proposal for development of the Signal Network library as a part of |
| | 10 | Google Summer of Code and evential inclusion into Boost. Depending on what is preferred, |
| | 11 | the Signal Network library can be included into Boost.Signals or considered as a separate library. |
| | 12 | |
| | 13 | If you're interested, you may want to examine the [http://dancinghacker.com/code/signet/ documentation for the prototype implementation]. |
| | 14 | |
| | 15 | The Signal Network library is to provide |
| | 16 | * a concise operator based syntax that facilitates construction and readiblity of signal networks |
| | 17 | * mechanisms that facilitate construction of signal network components |
| | 18 | * implemented building-block components that are applicable to a wide range of signal networks |
| | 19 | * detailed documentation (tutorial, examples and reference) of all of the above |
| | 20 | |
| | 21 | The development platforms are |
| | 22 | * OS X / Xcode with Apple's branch of GCC |
| | 23 | * Windows / MSVC8.0 |
| | 24 | |
| | 25 | == Motivation == |
| | 26 | |
| | 27 | Boost.Signals provides an excellent mechanism which can be used to dynamically configure the flow of data within |
| | 28 | a program. This is helpful for registering callbacks, for event passing, and for signal processing applications. |
| | 29 | |
| | 30 | However, when dealing with more complicated networks, there are several improvements to Boost.Signals |
| | 31 | that could facilitate the construction, configuration, and execution of said networks. Several categories which could use |
| | 32 | some improvement are listed below. |
| | 33 | |
| | 34 | For simplicity, the examples in this documentation deal with signals which carry numbers, |
| | 35 | and components which manipulate them. The same principles are applicable to many kinds of signal oriented |
| | 36 | applications (e.g., ones where the signals carry event information, video frames, audio buffers, etc.). |
| | 37 | |
| | 38 | === Conciseness and readability of code === |
| | 39 | In complex signal-based applications, many components are signal ''filters'' or some kind (i.e., they |
| | 40 | receive some input, process it, and send some output). For processing of any substantial complexity, |
| | 41 | each type of filter is most likely implemented as a class, with one or more member boost::signal |
| | 42 | objects serving as signal outputs, and one or more member functions serving as input slots. |
| | 43 | |
| | 44 | Suppose we would like to connect a network consisting of a signal generator, a couple of filters, |
| | 45 | and a couple of signal consumers (say, display components). The components might be declared as follows: |
| | 46 | |
| | 47 | {{{ |
| | 48 | #!cpp |
| | 49 | signal_generator generator; // contains a boost::signal accessible via signal_generator::default_signal() |
| | 50 | signal_filter1 filter1; // contains a boost::signal accessible via signal_filter1::default_signal(), |
| | 51 | // and a slot function operator() |
| | 52 | signal_filter2 filter2; // contains a boost::signal accessible via signal_filter2::default_signal(), |
| | 53 | // and a slot function operator() |
| | 54 | signal_display display1, display2; // contains a slot function operator() |
| | 55 | }}} |
| | 56 | |
| | 57 | To connect the network, the following would be necessary using Boost.Signals: |
| | 58 | |
| | 59 | ==== Boost.Signals syntax: ==== |
| | 60 | |
| | 61 | {{{ |
| | 62 | // connect the generator to filter1 |
| | 63 | generator.default_signal().connect(boost::bind(&signal_filter1::operator(), boost::ref(filter1))); |
| | 64 | // connect filter1 to filter2 |
| | 65 | filter1.default_signal().connect(boost::bind(&signal_filter2::operator(), boost::ref(filter2))); |
| | 66 | // connect the output of each filter to a display |
| | 67 | filter1.default_signal().connect(boost::bind(&signal_display::operator(), boost::ref(display1))); |
| | 68 | filter2.default_signal().connect(boost::bind(&signal_display::operator(), boost::ref(display2))); |
| | 69 | }}} |
| | 70 | |
| | 71 | The code above is rather long to write, and might not be particularly readable. What we would like to |
| | 72 | do instead is something more concise and readable: |
| | 73 | ==== Proposed/desired syntax: ==== |
| | 74 | |
| | 75 | {{{ |
| | 76 | // connect (>>=) generator to filter1, |
| | 77 | // branch (|) from filter1 to both display1 and filter2, |
| | 78 | // and connect (>>=) filter2 to display2. |
| | 79 | generator |
| | 80 | >>= filter1 |
| | 81 | | display1 |
| | 82 | | filter2 >>= display2; |
| | 83 | }}} |
| | 84 | |
| | 85 | The above code is much more concise, and after getting familiar with the syntax, understanding the structure of |
| | 86 | the signal network is easy and quick. |
| | 87 | |
| | 88 | === Flow control components === |
| | 89 | In many cases, we would like to modify the flow of signals after the network |
| | 90 | has been constructed. Boost.Signals allows us to change the network by disconnecting old or |
| | 91 | creating new connections. So, for example, if we wanted to introduce a second |
| | 92 | signal generator into the system (e.g., generator2), we could use signal::disconnect (or |
| | 93 | signal::disconnect_all_slots) |
| | 94 | and signal::connect to toggle between the two sources: |
| | 95 | |
| | 96 | ==== Boost.Signals flow control: ==== |
| | 97 | |
| | 98 | {{{ |
| | 99 | // switch to the other signal generator: |
| | 100 | generator.default_signal().disconnect_all_slots(); |
| | 101 | generator2.default_signal().connect(boost::bind(&signal_filter1::operator(), boost::ref(filter1))); |
| | 102 | }}} |
| | 103 | |
| | 104 | There are a few potential problems with this approach. First, the syntax is again perhaps a little too involved. |
| | 105 | And second, altering the |
| | 106 | network while signals are being sent may require extra care (especially in multi-threaded |
| | 107 | settings). Hence, depending on the situation, it might be difficult to use |
| | 108 | this approach |
| | 109 | to alternate between the two sources (perhaps a custom object would need to be written |
| | 110 | to choose the appropriate source). |
| | 111 | |
| | 112 | Instead, it would be desirable to have ready-made components which can be used to alter |
| | 113 | the flow of signals without changing the architecture of the network: |
| | 114 | |
| | 115 | ==== Proposed/desired flow control: ==== |
| | 116 | |
| | 117 | {{{ |
| | 118 | // introduce a selector into the network |
| | 119 | signal_selector selector; |
| | 120 | |
| | 121 | // the generators are now connected to the selector |
| | 122 | generator >>= selector.slot1; |
| | 123 | generator2 >>= selector.slot2; |
| | 124 | |
| | 125 | // and the rest of the network is now constructed as follows: |
| | 126 | selector |
| | 127 | >>= filter1 |
| | 128 | | display1 |
| | 129 | | filter2 >>= display2; |
| | 130 | |
| | 131 | |
| | 132 | // Now we could choose the source as follows: |
| | 133 | selector.select(1); // select input coming into slot1 |
| | 134 | ... |
| | 135 | selector.select(2); // select input coming into slot2 |
| | 136 | ... |
| | 137 | selector.select(0); // select no input |
| | 138 | }}} |
| | 139 | |
| | 140 | The latter approach offers more robust control, and can be implemented in a thread-safe way |
| | 141 | (safe even when the generated signals are in threads separate from the reconfiguring thread). |
| | 142 | Similar arguments can be made for other flow control components such as junctions and gates. |
| | 143 | |
| | 144 | === Other building-block signal network components === |
| | 145 | There are many other components that are usable in various signal network settings. |
| | 146 | The Signal Network library would provide a set of such commonly needed components, |
| | 147 | such as templates for signal generators, collectors, threading components, etc. |