interest in a "signal flow" library?

Is there any interest in a library which facilitates the implementation and interconnection of objects using Boost.Signals? For example, in a video processing scenario, one might be using the following objects: * frame_rate - generates a void() signal at a consistent frame rate * video_generator - upon receiving a void() signal, produces a signal containing an image (e.g., a frame grabbed from a camera or read from a file) * differencer - upon receiving an image signal, outputs the pixel-difference between the image and the previous image received * flipper - upon receiving an image signal, outputs the horizontally flipped image * analysis - upon receiving an image signal, performs some sort of analysis and outputs a feature vector signal * database - upon receiving a feature vector signal, outputs an image from the database based on some relationship * display1, display2 - upon receiving an image, displays it in a window It would be nice to be able to easily connect these objects via intuitive signal flow "diagrams": // perform the whole video analysis and display the results frame_rate >>= video_generator >>= differencer >>= flipper >>= analysis >>= database >>= display1; // also display the video input video_generator >>= display2; ... or, to specify the entire signal flow in one shot using something like this: frame_rate >>= video_generator >= (differencer >>= flipper >>= analysis >>= database >>= display1) >= display2; Boost.Signals allows us to interconnect the components, and also change the connections as needed(for example, one could skip the flipper if necessary). However, in the absence of an easy connection mechanism such as the one above, one has to use signal::connect(...) for each connection, which can be tedious with a lot of connections, and not as readable. As a starting point, I implemented a little library that provides the above connection syntax (and a little more) - you can find most of it documented as the signal_link class at http://tinyurl.com/2npfcr. The code is attached - I've tested it under both VS.NET2005 and GCC 4.0.1 on OSX/Xcode. It has a little test app with test cases (an included script called g++_it should build it using g++ if you have boost includes and libs on your path). If you find this concept interesting please take a look at the documentation and the code, I'd be most interested to hear your feedback. There are quite a few things still missing (for example, the slot_selector mechanism is not fully integrated with the operators, and it's not possible to disconnect signals in all ways one would want to), so suggestions are more than welcome. In particular: * The current signal_link class provides a default output object. Would it be better to let the descendant class provide its own and supply a reference to signal_link? * I am having problems using signal::disconnect to disconnect equivalent slots (even trying to compile examples from the web documentation). I'm using 1_33_1. Any ideas? * I'm wondering whether the choice of operators (operator(), >>=., >=) used is appropriate or whether there are better alternatives. * Is there a better alternative to the current slot_selector mechanism? Also, please let me know whether you think this would be an interesting addition to Boost. I think the concept might be useful in any situation where the problem can be visualized as a flow of data/signals (e.g., any signal processing application). Regards, Stjepan

Stjepan Rajko wrote:
Also, please let me know whether you think this would be an interesting addition to Boost.
Yes, I think (if done right) this one will be useful for all kinds of software. I'll post a more detailed reply later, after having a look at the code. I think you need a pulling evaluation scheme: Making the (final) sink pull rather than the (possibly void-) source push: In your example, a Timer would request the Display to be updated, which in turn would requests an Image ... and so on, until finally a frame is pulled from the video input. This way operator nodes (with 1 source >=1 sink) and caching (to not reevaluate unchanged paths) become much easier to implement. So much easier, that I'm not even sure pushing evaluation is needed at all. Regards, Tobias

Is there any interest in a library which facilitates the implementation and interconnection of objects using Boost.Signals?
Yes, much interest.
For example, in a video processing scenario, one might be using the following objects:
* frame_rate - generates a void() signal at a consistent frame rate * video_generator - upon receiving a void() signal, produces a signal containing an image (e.g., a frame grabbed from a camera or read from a file) * differencer - upon receiving an image signal, outputs the pixel-difference between the image and the previous image received * flipper - upon receiving an image signal, outputs the horizontally flipped image * analysis - upon receiving an image signal, performs some sort of analysis and outputs a feature vector signal * database - upon receiving a feature vector signal, outputs an image from the database based on some relationship * display1, display2 - upon receiving an image, displays it in a window
It would be nice to be able to easily connect these objects via intuitive signal flow "diagrams":
// perform the whole video analysis and display the results frame_rate >>= video_generator >>= differencer >>= flipper >>= analysis >>= database >>= display1;
// also display the video input video_generator >>= display2;
... or, to specify the entire signal flow in one shot using something like this: frame_rate
= video_generator >= (differencer >>= flipper >>= analysis >>= database >>= display1) >= display2;
I didn't look at the library yet, however, in a similar context I had the requirement to perform some operations in parallel. Thus, I wonder if this could be supported by the syntax, e.g., video_generator >>= ( effect1 && effect2 ) >>= image_sum >>= display where effect1 and effect2 are executed in parallel (for example, by different threads of a thread_group); image_sum (which expects two arguments) is executed only when both effect1 and effect2 are completed. Regards, Paolo

Hello, Signal_links looks like a nice light-weight feature to have when developing event dispatching applications using Boost.Signal. From its current syntax, looks like it will work most naturally for linear pipeline and tree like connection topologies, for more complicated connection topologies (such as mesh or acyclic graph), we will have to break it up into pipeline or trees and set up them in several steps? that said, it still makes code cleaner and clearer. could we have some samples showing dynamic reconfiguration works (adding/removing new senders/recvers)? The scenario Paolo mentioned: "video_generator >>= ( effect1 && effect2 ) >>= image_sum >>= display" in fact the middle part of it "( effect1 && effect2 ) >>= image_sum" is so called "join" pattern in message passing. i have written a boost based framework (http://channel.sourceforge.net) for asynchronous events and message passing which support both choice/join patterns, executing callbacks in thread pools, push/pull models and other stuff which you may find interesting, although it doesnt have the elegant api of Boost.Signal. Regards, yigong On 2/21/07, Paolo Coletta <paolo@rcpstudio.it> wrote:
where effect1 and effect2 are executed in parallel (for example, by different threads of a thread_group); image_sum (which expects two arguments) is executed only when both effect1 and effect2 are completed.
participants (4)
-
Paolo Coletta
-
Stjepan Rajko
-
Tobias Schwinger
-
Yigong Liu