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