
On Thu, Sep 4, 2008 at 1:06 AM, Kowalke Oliver (QD IT PA SI) <Oliver.Kowalke@qimonda.com> wrote:
Hello,
I took a quick look into the lib and I've following questions:
- How does Boost.DataFlow support exchanging data in both directions between two components (duplex communication)? Example: stack of network-protocols:
service_contract >>= serializer >>= encoder >>= protocol_1 >>= protocol_2 >>= transport (send data) transport >>= protocol_2 >>= protocol_1 >>= encoder >>= deserializer >>= service_contract (receive data)
Depends on the exact details. If the communication is always such that the left component initiates the exchange by sending its piece of data, and then the right component responds, in the Dataflow.Signals layer you could use a signature like `type1(type2), i.e. use the argument to send the data to the right and the return value to send the data to the left. Here is an example (untested) class duplex_multiplier : public signals::filter<duplex_multiplier, int(int)> { public: int operator()(int x) { // double the value received from the left, and send that to the right int response_from_right = out(x*2); // then return triple the response to the component on the left return 3 * response_from_right; } }; // signal consumers don't need to know their signature class loop_back : public signals::consumer<loop_back> { public: int operator()(int x); { // just return the received value back to the left return x; } }; // now: duplex_multiplier a,b,c; loop_back d; // the following connections are bidirectional because of the int(int) signature // so >>= is misleading and a different operator might be better to use a >>= b >>= c >>= d; int response = a(1); // should return 1*2*2*2*3*3*3 If in your scenario a component would need to respond instantly (before sending data to the right and receiving a response), then it would need to send the rightward signal in a separate thread. If, on the other hand, you have a true duplex scenario where both the leftmost and rightmost component can initiate a signal, then each component would need an additional signal. The network would then look something like: c1 >>= c2 >>= c3 >>= c4 c4.left_signal() >>= c3.left_signal() >>= c2.left_signal() >>= c1 This is similar to: http://www.dancinghacker.com/code/dataflow/dataflow/signals/introduction/tut...
- If one consumer is connected to multiple producers, how can the consumer selectively disconnect from specific producers?
I would recommend storing the connection object and using it to break the connection, as shown here: http://www.dancinghacker.com/code/dataflow/dataflow/signals/introduction/tut... At one point, I put together an example of how this tracking of connection objects by the consumer could be done automatically: http://svn.boost.org/svn/boost/sandbox/SOC/2007/signals/libs/dataflow/exampl... http://svn.boost.org/svn/boost/sandbox/SOC/2007/signals/libs/dataflow/exampl... In these examples, the consumer was programmed to disconnect itself from any producer that sends it a signal after it has already received a specified number of signals, but the logic could be changed.
Contrary to some other posts -I find the syntax of ovelroaded operators not confusing:
= push sematic =<< pull semantic
The pipe operator '|' could also be used in the parallel execution semantic.
I am also happy with >>= (and adding <<= to indicate pull semantics), but the example above showed another problem - if the connection is bidirectional, neither >>= or <<= seem appropriate. What do people think of making the operator choice completely up to the user (i.e., the user can specify what operator they would like to use for what operation, with some default mappings provided)? Thanks for taking a look at the library! Best, Stjepan