Boost logo

Boost-Commit :

From: stipe_at_[hidden]
Date: 2008-06-24 15:12:44


Author: srajko
Date: 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
New Revision: 46660
URL: http://svn.boost.org/trac/boost/changeset/46660

Log:
initial Dataflow.Managed add
Added:
   sandbox/SOC/2007/signals/boost/dataflow/managed/
   sandbox/SOC/2007/signals/boost/dataflow/managed/component.hpp (contents, props changed)
   sandbox/SOC/2007/signals/boost/dataflow/managed/network.hpp (contents, props changed)
   sandbox/SOC/2007/signals/boost/dataflow/managed/port.hpp (contents, props changed)
   sandbox/SOC/2007/signals/libs/dataflow/test/managed/
   sandbox/SOC/2007/signals/libs/dataflow/test/managed/Jamfile (contents, props changed)
   sandbox/SOC/2007/signals/libs/dataflow/test/managed/test_network.cpp (contents, props changed)
   sandbox/SOC/2007/signals/libs/dataflow/test/managed/test_port.cpp (contents, props changed)
Text files modified:
   sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/dataflow.xcodeproj/project.pbxproj | 28 ++++++++++++++++++++++++++++
   sandbox/SOC/2007/signals/libs/dataflow/test/Jamfile.v2 | 3 ++-
   2 files changed, 30 insertions(+), 1 deletions(-)

Added: sandbox/SOC/2007/signals/boost/dataflow/managed/component.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/boost/dataflow/managed/component.hpp 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -0,0 +1,37 @@
+// Copyright 2008 Stjepan Rajko.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DATAFLOW_MANAGED_COMPONENT_HPP
+#define BOOST_DATAFLOW_MANAGED_COMPONENT_HPP
+
+namespace boost { namespace dataflow { namespace managed {
+
+class network;
+
+class component
+{
+public:
+ component(network &network_context) : m_network_context(network_context), m_topological_sort_index(0)
+ {};
+ virtual ~component(){}
+ network &network_context()
+ { return m_network_context; }
+ virtual void invoke(){};
+ void topological_sort_index(unsigned index)
+ {
+ m_topological_sort_index = index;
+ }
+ unsigned topological_sort_index() const
+ {
+ return m_topological_sort_index;
+ }
+private:
+ network &m_network_context;
+ unsigned m_topological_sort_index;
+};
+
+}}}
+
+#endif // BOOST_DATAFLOW_MANAGED_COMPONENT_HPP
\ No newline at end of file

Added: sandbox/SOC/2007/signals/boost/dataflow/managed/network.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/boost/dataflow/managed/network.hpp 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -0,0 +1,68 @@
+// Copyright 2008 Stjepan Rajko.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DATAFLOW_MANAGED_NETWORK_HPP
+#define BOOST_DATAFLOW_MANAGED_NETWORK_HPP
+
+#include <vector>
+#include <set>
+
+#include <boost/dataflow/managed/component.hpp>
+
+namespace boost { namespace dataflow { namespace managed {
+
+
+namespace detail {
+ struct component_ptr_cmp
+ {
+ bool operator()(const component * const lhs, const component * const rhs) const
+ {
+ return lhs->topological_sort_index() < rhs->topological_sort_index();
+ }
+ };
+}
+
+class network
+{
+public:
+ void notify_change(component &changed)
+ {
+ m_changed.insert(&changed);
+ }
+ typedef std::set<component *, detail::component_ptr_cmp> changed_type;
+ const changed_type &changed_components()
+ {
+ return m_changed;
+ }
+ typedef std::vector<component *> topological_sort_type;
+ void topological_sort(const topological_sort_type &topological_sort)
+ {
+ m_changed.clear();
+ for(topological_sort_type::const_iterator it=topological_sort.begin(); it!=topological_sort.end(); it++)
+ (*it)->topological_sort_index(it - topological_sort.begin());
+ for(topological_sort_type::const_iterator it=topological_sort.begin(); it!=topological_sort.end(); it++)
+ m_changed.insert(*it);
+ }
+ void update()
+ {
+ while(!m_changed.empty())
+ {
+ component *next = *m_changed.begin();
+ m_changed.erase(m_changed.begin());
+ next->invoke();
+ }
+ }
+private:
+ changed_type m_changed;
+};
+
+void notify_change(component &c)
+{
+ c.network_context().notify_change(c);
+}
+
+} } }
+
+#endif // BOOST_DATAFLOW_MANAGED_PORT_HPP
\ No newline at end of file

Added: sandbox/SOC/2007/signals/boost/dataflow/managed/port.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/boost/dataflow/managed/port.hpp 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -0,0 +1,99 @@
+// Copyright 2008 Stjepan Rajko.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DATAFLOW_MANAGED_PORT_HPP
+#define BOOST_DATAFLOW_MANAGED_PORT_HPP
+
+#include <boost/dataflow/managed/component.hpp>
+#include <boost/dataflow/support/tags.hpp>
+#include <set>
+#include <stdexcept>
+
+namespace boost { namespace dataflow { namespace managed {
+
+class port_base
+{
+public:
+ port_base(component &component_context) : m_component_context(component_context)
+ {
+
+ };
+ component &component_context()
+ { return m_component_context; }
+private:
+ component &m_component_context;
+};
+
+template<typename T, typename PortCategory>
+class port;
+
+template<typename T>
+void connect(port<T, ports::producer> &producer, port<T, ports::consumer> &consumer)
+{
+ if(consumer.connected())
+ disconnect(consumer.connected_producer(), consumer);
+ producer.m_consumers.insert(&consumer);
+ consumer.m_producer = &producer;
+}
+
+template<typename T>
+void disconnect(port<T, ports::producer> &producer, port<T, ports::consumer> &consumer)
+{
+ producer.m_consumers.erase(&consumer);
+ consumer.m_producer = 0;
+}
+
+template<typename T>
+class port<T, ports::producer> : public port_base
+{
+public:
+ port(component &component_context) : port_base(component_context)
+ {
+ };
+ void set(const T &value)
+ {
+ m_value = value;
+ for(typename consumers_type::iterator it=m_consumers.begin(); it!=m_consumers.end(); it++)
+ notify_change((*it)->component_context());
+ }
+ T &get()
+ { return m_value; }
+private:
+ T m_value;
+ typedef std::set<port<T, ports::consumer> *> consumers_type;
+ consumers_type m_consumers;
+
+ friend void connect<T>(port<T, ports::producer> &producer, port<T, ports::consumer> &consumer);
+ friend void disconnect<T>(port<T, ports::producer> &producer, port<T, ports::consumer> &consumer);
+};
+
+template<typename T>
+class port<T, ports::consumer> : public port_base
+{
+public:
+ port(component &component_context)
+ : port_base(component_context), m_producer(0)
+ {
+ };
+ bool connected() const
+ { return m_producer != 0; }
+ port<T, ports::producer> &connected_producer()
+ { return *m_producer; }
+ T &get()
+ {
+ if (!m_producer)
+ throw(std::runtime_error("consumer port has no producer"));
+ return m_producer->get();
+ }
+private:
+ port<T, ports::producer> *m_producer;
+
+ friend void connect<T>(port<T, ports::producer> &producer, port<T, ports::consumer> &consumer);
+ friend void disconnect<T>(port<T, ports::producer> &producer, port<T, ports::consumer> &consumer);
+};
+
+} } }
+
+#endif // BOOST_DATAFLOW_MANAGED_PORT_HPP
\ No newline at end of file

Modified: sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/dataflow.xcodeproj/project.pbxproj
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/dataflow.xcodeproj/project.pbxproj (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/dataflow.xcodeproj/project.pbxproj 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -129,6 +129,12 @@
                 089AE5BC0D79CE5E00AB9DA8 /* test_bind_mem_fn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_bind_mem_fn.cpp; sourceTree = "<group>"; };
                 089AE6390D79D95C00AB9DA8 /* member_function_signature.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = member_function_signature.hpp; sourceTree = "<group>"; };
                 089B93720D5AA99700F6EEAA /* test_filter_base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_filter_base.cpp; sourceTree = "<group>"; };
+ 089C08A40E0AFA7200397123 /* component.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = component.hpp; sourceTree = "<group>"; };
+ 089C08A50E0AFAA500397123 /* port.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = port.hpp; sourceTree = "<group>"; };
+ 089C08AC0E0AFB7800397123 /* Jamfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.jam; path = Jamfile; sourceTree = "<group>"; };
+ 089C08AE0E0AFBB600397123 /* test_port.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_port.cpp; sourceTree = "<group>"; };
+ 089C08BB0E0AFDF400397123 /* network.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = network.hpp; sourceTree = "<group>"; };
+ 089C098C0E0B11FF00397123 /* test_network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_network.cpp; sourceTree = "<group>"; };
                 089CDA940D832AD200731C70 /* tutorial.qbk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tutorial.qbk; sourceTree = "<group>"; };
                 089CDAA90D8333CC00731C70 /* unary_operation.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = unary_operation.hpp; sourceTree = "<group>"; };
                 08A0B20C0D21C4A90054AD32 /* cppgui_example.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cppgui_example.cpp; sourceTree = "<group>"; };
@@ -397,6 +403,26 @@
                         path = examples;
                         sourceTree = "<group>";
                 };
+ 089C08A30E0AFA5E00397123 /* managed */ = {
+ isa = PBXGroup;
+ children = (
+ 089C08A40E0AFA7200397123 /* component.hpp */,
+ 089C08A50E0AFAA500397123 /* port.hpp */,
+ 089C08BB0E0AFDF400397123 /* network.hpp */,
+ );
+ path = managed;
+ sourceTree = "<group>";
+ };
+ 089C08A60E0AFAF500397123 /* managed */ = {
+ isa = PBXGroup;
+ children = (
+ 089C08AC0E0AFB7800397123 /* Jamfile */,
+ 089C08AE0E0AFBB600397123 /* test_port.cpp */,
+ 089C098C0E0B11FF00397123 /* test_network.cpp */,
+ );
+ path = managed;
+ sourceTree = "<group>";
+ };
                 08A0B20A0D21C4050054AD32 /* cppgui_gui */ = {
                         isa = PBXGroup;
                         children = (
@@ -415,6 +441,7 @@
                 08C675960C13A03E00D85379 /* test */ = {
                         isa = PBXGroup;
                         children = (
+ 089C08A60E0AFAF500397123 /* managed */,
                                 08C675970C13A03E00D85379 /* Jamfile.v2 */,
                                 08F5FF060D07082200FDBAEE /* blueprint */,
                                 08F71D3D0CA3547C0010099E /* signals */,
@@ -803,6 +830,7 @@
                 08FC25BA0C45B60E00F59CDD /* dataflow */ = {
                         isa = PBXGroup;
                         children = (
+ 089C08A30E0AFA5E00397123 /* managed */,
                                 08F01F950C470E1500C0ED27 /* support */,
                                 08EF9B200C5D506A00D4D206 /* signals */,
                                 08F265440CEAC22400DA01C9 /* blueprint */,

Modified: sandbox/SOC/2007/signals/libs/dataflow/test/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/test/Jamfile.v2 (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/Jamfile.v2 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -23,4 +23,5 @@
 
 build-project signals ;
 build-project blueprint ;
-build-project utility ;
\ No newline at end of file
+build-project utility ;
+build-project managed ;
\ No newline at end of file

Added: sandbox/SOC/2007/signals/libs/dataflow/test/managed/Jamfile
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/managed/Jamfile 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -0,0 +1,16 @@
+# Copyright 2008 Stjepan Rajko.
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+
+project dataflow/test/managed
+ : requirements
+ <include>../../../..
+ <define>BOOST_ALL_NO_LIB=1
+ ;
+
+run test_port.cpp ;
+run test_network.cpp ;
+

Added: sandbox/SOC/2007/signals/libs/dataflow/test/managed/test_network.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/managed/test_network.cpp 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -0,0 +1,143 @@
+// Copyright Stjepan Rajko 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <boost/dataflow/managed/port.hpp>
+#include <boost/dataflow/managed/network.hpp>
+#include <boost/assign/std/vector.hpp>
+
+#include <boost/test/included/test_exec_monitor.hpp>
+
+namespace df=boost::dataflow;
+
+// source just provides an output port
+class source : public df::managed::component
+{
+public:
+ source(df::managed::network &network, int value)
+ : df::managed::component(network), output(*this)
+ {
+ output.set(value);
+ }
+ df::managed::port<int, df::ports::producer> output;
+};
+
+// adder has two input ports and an output port.
+// invoking adds the two inputs into the output.
+class adder : public df::managed::component
+{
+public:
+ adder(df::managed::network &network)
+ : component(network), output(*this), input1(*this), input2(*this)
+ , invoke_count(0)
+ {}
+ void invoke()
+ {
+ invoke_count++;
+ output.set(input1.get()+input2.get());
+ }
+
+ df::managed::port<int, df::ports::producer> output;
+ df::managed::port<int, df::ports::consumer> input1;
+ df::managed::port<int, df::ports::consumer> input2;
+ unsigned invoke_count;
+};
+
+// multiplier has two input ports and an output port.
+// invoking multipilies the two inputs into the output.
+class multiplier : public df::managed::component
+{
+public:
+ multiplier(df::managed::network &network)
+ : component(network), output(*this), input1(*this), input2(*this)
+ , invoke_count(0)
+ {}
+ void invoke()
+ {
+ invoke_count++;
+ output.set(input1.get()*input2.get());
+ }
+
+ df::managed::port<int, df::ports::producer> output;
+ df::managed::port<int, df::ports::consumer> input1;
+ df::managed::port<int, df::ports::consumer> input2;
+ unsigned invoke_count;
+};
+
+int test_main(int, char* [])
+{
+ // our network
+ df::managed::network network;
+
+ // our four sources with initial values
+ source sourceA(network, 0);
+ source sourceB(network, 1);
+ source sourceC(network, 2);
+ source sourceD(network, 3);
+
+ // two adders and a multiplier
+ adder AplusB(network), CplusD(network);
+ multiplier ApBtimesCpD(network);
+
+ // ---Connect the dataflow network ---------------------
+ //
+ // ,---------. ,---.
+ // | sourceA | ----> | A | ,---.
+ // `---------' | + | ----> | A |
+ // ,---------. | B | | + |
+ // | sourceB | ----> | | | B |
+ // `---------' `---' | |
+ // ,---------. ,---. | * |
+ // | sourceC | ----> | | | |
+ // `---------' | C | | C |
+ // ,---------. | + | ----> | + |
+ // | sourceD | ----> | D | | D |
+ // `---------' `---' `---'
+ //
+ // -----------------------------------------------------
+ connect(sourceA.output, AplusB.input1);
+ connect(sourceB.output, AplusB.input2);
+ connect(sourceC.output, CplusD.input1);
+ connect(sourceD.output, CplusD.input2);
+ connect(AplusB.output, ApBtimesCpD.input1);
+ connect(CplusD.output, ApBtimesCpD.input2);
+
+ using namespace boost::assign;
+
+ // provide a hard coded topological sort for now
+ std::vector<df::managed::component *> topological_sort;
+ topological_sort += &sourceA, &sourceB, &sourceC, &sourceD, &AplusB, &CplusD, &ApBtimesCpD;
+ network.topological_sort(topological_sort);
+
+ // update will invoke all components that need to be invoked
+ network.update();
+ BOOST_CHECK_EQUAL(ApBtimesCpD.output.get(), (0+1)*(2+3));
+ BOOST_CHECK_EQUAL(AplusB.invoke_count, 1u);
+ BOOST_CHECK_EQUAL(CplusD.invoke_count, 1u);
+ BOOST_CHECK_EQUAL(ApBtimesCpD.invoke_count, 1u);
+
+ // change the output of sourceA
+ sourceA.output.set(4);
+ network.update();
+ BOOST_CHECK_EQUAL(ApBtimesCpD.output.get(), (4+1)*(2+3));
+ BOOST_CHECK_EQUAL(AplusB.invoke_count, 2u);
+ // C and D did not change, hence CplusD should not get invoked!
+ BOOST_CHECK_EQUAL(CplusD.invoke_count, 1u);
+ BOOST_CHECK_EQUAL(ApBtimesCpD.invoke_count, 2u);
+
+ sourceC.output.set(5);
+ sourceD.output.set(6);
+ network.update();
+ BOOST_CHECK_EQUAL(ApBtimesCpD.output.get(), (4+1)*(5+6));
+ // A and B did not change, hence AplusB should not get invoked!
+ BOOST_CHECK_EQUAL(AplusB.invoke_count, 2u);
+ BOOST_CHECK_EQUAL(CplusD.invoke_count, 2u);
+ BOOST_CHECK_EQUAL(ApBtimesCpD.invoke_count, 3u);
+
+ return 0;
+} // int test_main(int, char* [])
+
+
+

Added: sandbox/SOC/2007/signals/libs/dataflow/test/managed/test_port.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/managed/test_port.cpp 2008-06-24 15:12:43 EDT (Tue, 24 Jun 2008)
@@ -0,0 +1,41 @@
+// Copyright Stjepan Rajko 2008. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <boost/dataflow/managed/port.hpp>
+#include <boost/dataflow/managed/network.hpp>
+
+#include <boost/test/included/test_exec_monitor.hpp>
+
+int test_main(int, char* [])
+{
+ using namespace boost;
+ namespace df=boost::dataflow;
+
+ df::managed::network network;
+ df::managed::component input_component(network);
+ df::managed::component output_component(network);
+
+ df::managed::port<int, df::ports::producer> output(output_component);
+ df::managed::port<int, df::ports::consumer> input(input_component);
+
+ BOOST_CHECK_EQUAL(output.get(), 0);
+ BOOST_CHECK_THROW(input.get(), std::runtime_error);
+
+ BOOST_CHECK_EQUAL(network.changed_components().size(), 0u);
+ connect(output, input);
+ output.set(1);
+
+ BOOST_CHECK_EQUAL(output.get(), 1);
+ BOOST_CHECK_EQUAL(input.get(), 1);
+
+ BOOST_CHECK_EQUAL(network.changed_components().size(), 1u);
+ BOOST_CHECK_EQUAL(*network.changed_components().begin(), &input_component);
+
+ return 0;
+} // int test_main(int, char* [])
+
+
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk