$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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* [])
+
+
+