|
Boost-Commit : |
From: stipe_at_[hidden]
Date: 2007-11-14 00:39:01
Author: srajko
Date: 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
New Revision: 41076
URL: http://svn.boost.org/trac/boost/changeset/41076
Log:
add GIL example, improve VTK example and Port docs, start ReflectiveComponent, add operator include file template
Added:
sandbox/SOC/2007/signals/boost/dataflow/support/reflective_component.hpp (contents, props changed)
sandbox/SOC/2007/signals/boost/dataflow/templates/operator.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/distributed_example.qbk
- copied, changed from r41018, /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/gil_example.qbk
- copied, changed from r41018, /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/vtk_example.qbk
- copied, changed from r41018, /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk
sandbox/SOC/2007/signals/libs/dataflow/example/VTK/vtk_dataflow_support.hpp
- copied, changed from r41018, /sandbox/SOC/2007/signals/libs/dataflow/example/VTK/support.hpp
sandbox/SOC/2007/signals/libs/dataflow/example/signals/gil_example.cpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/test/test_reflective_component.cpp (contents, props changed)
Removed:
sandbox/SOC/2007/signals/libs/dataflow/example/VTK/operators.hpp
sandbox/SOC/2007/signals/libs/dataflow/example/VTK/support.hpp
Text files modified:
sandbox/SOC/2007/signals/boost/dataflow/signals/component/multiplexer.hpp | 8
sandbox/SOC/2007/signals/boost/dataflow/support/component.hpp | 3
sandbox/SOC/2007/signals/boost/dataflow/support/port/detail/port_traits_sequence.hpp | 2
sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/signal_network.xcodeproj/project.pbxproj | 28 +
sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk | 75 +++
sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk | 10
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk | 281 ------------
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/distributed_example.qbk | 623 ------------------------------
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/gil_example.qbk | 818 ++++++++-------------------------------
sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/vtk_example.qbk | 526 +++---------------------
sandbox/SOC/2007/signals/libs/dataflow/doc/port_concepts.qbk | 64 ++
sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone.cxx | 31
sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone2.cxx | 11
sandbox/SOC/2007/signals/libs/dataflow/example/VTK/vtk_dataflow_support.hpp | 32 +
sandbox/SOC/2007/signals/libs/dataflow/example/signals/Jamfile.v2 | 2
sandbox/SOC/2007/signals/libs/dataflow/test/Jamfile.v2 | 1
sandbox/SOC/2007/signals/libs/dataflow/test/test_component.cpp | 1
sandbox/SOC/2007/signals/libs/dataflow/test/test_port.cpp | 124 ++++++
18 files changed, 612 insertions(+), 2028 deletions(-)
Modified: sandbox/SOC/2007/signals/boost/dataflow/signals/component/multiplexer.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signals/component/multiplexer.hpp (original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signals/component/multiplexer.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -43,7 +43,13 @@
void select(int selector)
{ base_type::member = selector; }
- typedef boost::fusion::map<
+ slot_selector<void(int), multiplexer>
+ select_slot()
+ {
+ return make_slot_selector<void(int)> (&multiplexer::select, *this);
+ }
+
+ typedef boost::fusion::map<
boost::fusion::pair<boost::dataflow::signals::producer<Signature>, slot_selector<Signature, multiplexer> >,
boost::fusion::pair<
boost::dataflow::signals::producer<typename base_type::fused_signature_type>,
Modified: sandbox/SOC/2007/signals/boost/dataflow/support/component.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/support/component.hpp (original)
+++ sandbox/SOC/2007/signals/boost/dataflow/support/component.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -9,15 +9,12 @@
#include <boost/dataflow/detail/enable_if_defined.hpp>
#include <boost/mpl/and.hpp>
-#include <boost/mpl/at.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
-//temp
-#include <boost/mpl/vector.hpp>
namespace boost { namespace dataflow {
Modified: sandbox/SOC/2007/signals/boost/dataflow/support/port/detail/port_traits_sequence.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/support/port/detail/port_traits_sequence.hpp (original)
+++ sandbox/SOC/2007/signals/boost/dataflow/support/port/detail/port_traits_sequence.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -27,7 +27,7 @@
template<typename PortCategory, typename T, int N>
struct lazy_is_same_port_traits_port_category
{
- typedef typename is_same<PortCategory, typename mpl::at_c<typename T::port_traits, N>::type::port_category>::type type;
+ typedef typename is_same<PortCategory, typename mpl::at_c<typename T::port_traits, N>::type::category>::type type;
};
}
Added: sandbox/SOC/2007/signals/boost/dataflow/support/reflective_component.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/boost/dataflow/support/reflective_component.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -0,0 +1,56 @@
+// Copyright 2007 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_SUPPORT_COMPONENT_INTROSPECTION_HPP
+#define BOOST_DATAFLOW_SUPPORT_COMPONENT_INTROSPECTION_HPP
+
+#include <boost/dataflow/support/component.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/utility/result_of.hpp>
+
+
+namespace boost { namespace dataflow {
+
+namespace extension {
+
+ template<typename ComponentTraits, typename Enable=void>
+ struct get_component_port_impl
+ {
+ typedef void result_type;
+
+ struct detail
+ {
+ typedef void not_specialized;
+ };
+
+ template<typename Component, typename T>
+ void operator()(Component &, T)
+ {
+ // Error: get_component_port_impl has not been
+ // implemented for ComponentTraits.
+ BOOST_STATIC_ASSERT(sizeof(Component)==0);
+ }
+ };
+
+} // namespace extension
+
+template<typename Mechanism, typename T, typename Component>
+typename result_of<
+ extension::get_component_port_impl<
+ typename component_traits_of<Mechanism, Component>::type
+ >(Component &, T)>::type
+get_component_port(Component &component)
+{
+ return
+ extension::get_component_port_impl<
+ typename component_traits_of<Mechanism, Component>::type
+ >()(component, T());
+}
+
+} } // namespace boost::dataflow
+
+
+#endif // BOOST_DATAFLOW_SUPPORT_COMPONENT_INTROSPECTION_HPP
\ No newline at end of file
Added: sandbox/SOC/2007/signals/boost/dataflow/templates/operator.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/boost/dataflow/templates/operator.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -0,0 +1,59 @@
+// Copyright Stjepan Rajko 2007. 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)
+
+
+#ifndef DATAFLOW_TEMPLATE_MECHANISM
+#error DATAFLOW_TEMPLATE_MECHANISM undefined.
+#endif
+#ifndef DATAFLOW_TEMPLATE_BINARY_OPERATION
+#error DATAFLOW_TEMPLATE_BINARY_OPERATION undefined.
+#endif
+#ifndef DATAFLOW_TEMPLATE_BINARY_OPERATION
+#error DATAFLOW_TEMPLATE_OPERATOR undefined.
+#endif
+
+template<typename Producer, typename Consumer>
+typename boost::enable_if<
+ boost::mpl::and_<
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::producer, Producer>,
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::consumer, Consumer>
+ >,
+ Producer &
+>::type
+operator DATAFLOW_TEMPLATE_OPERATOR (Producer &producer, Consumer &consumer)
+{ DATAFLOW_TEMPLATE_BINARY_OPERATION(producer, consumer); return producer;}
+
+template<typename Producer, typename Consumer>
+typename boost::enable_if<
+ boost::mpl::and_<
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::producer, Producer>,
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::consumer, Consumer>
+ >,
+ Producer &
+>::type
+operator DATAFLOW_TEMPLATE_OPERATOR (Producer &producer, const Consumer &consumer)
+{ DATAFLOW_TEMPLATE_BINARY_OPERATION(producer, consumer); return producer;}
+
+template<typename Producer, typename Consumer>
+typename boost::enable_if<
+ boost::mpl::and_<
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::producer, Producer>,
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::consumer, Consumer>
+ >,
+ const Producer &
+>::type
+operator DATAFLOW_TEMPLATE_OPERATOR (const Producer &producer, Consumer &consumer)
+{ DATAFLOW_TEMPLATE_BINARY_OPERATION(producer, consumer); return producer;}
+
+template<typename Producer, typename Consumer>
+typename boost::enable_if<
+ boost::mpl::and_<
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::producer, Producer>,
+ boost::dataflow::is_port<DATAFLOW_TEMPLATE_MECHANISM, boost::dataflow::ports::consumer, Consumer>
+ >,
+ const Producer &
+>::type
+operator DATAFLOW_TEMPLATE_OPERATOR (const Producer &producer, const Consumer &consumer)
+{ DATAFLOW_TEMPLATE_BINARY_OPERATION(producer, consumer); return producer;}
Modified: sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/signal_network.xcodeproj/project.pbxproj
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/signal_network.xcodeproj/project.pbxproj (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/build/xcodeide/signal_network.xcodeproj/project.pbxproj 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -80,6 +80,7 @@
0800AC390C8CAAC300994538 /* boost-build.jam */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.jam; name = "boost-build.jam"; path = "../../../../boost-build.jam"; sourceTree = SOURCE_ROOT; };
0800AC3A0C8CAAC300994538 /* Jamfile.v2 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = Jamfile.v2; path = ../../../../Jamfile.v2; sourceTree = SOURCE_ROOT; };
0800AC3B0C8CAAC300994538 /* project-root.jam */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.jam; name = "project-root.jam"; path = "../../../../project-root.jam"; sourceTree = SOURCE_ROOT; };
+ 0801B4370CE9488B00A7A8D1 /* operator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = operator.hpp; sourceTree = "<group>"; };
08061C2D0CBEE985002DC710 /* binary_operation.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = binary_operation.hpp; sourceTree = "<group>"; };
08061C980CBEF0C6002DC710 /* keyed_port.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = keyed_port.hpp; sourceTree = "<group>"; };
08061CC40CBEF3F7002DC710 /* port_map.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = port_map.hpp; sourceTree = "<group>"; };
@@ -87,7 +88,10 @@
083FD3B90C62A4CB00EF3F6B /* concepts.qbk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = concepts.qbk; sourceTree = "<group>"; };
083FD3C10C62A75B00EF3F6B /* concepts.qbk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = concepts.qbk; sourceTree = "<group>"; };
083FD3C60C62A7F600EF3F6B /* phoenix.qbk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = phoenix.qbk; sourceTree = "<group>"; };
+ 084467150CE790B300B3CFDF /* test_reflective_component.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = test_reflective_component.cpp; sourceTree = "<group>"; };
+ 0844671B0CE7918C00B3CFDF /* reflective_component.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = reflective_component.hpp; sourceTree = "<group>"; };
084482560CA0B37200B88137 /* operators.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = operators.hpp; sourceTree = "<group>"; };
+ 084D2E6E0CE7DFE900E861FA /* gil_example.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gil_example.cpp; sourceTree = "<group>"; };
08668C4E0C19A16300ACB19A /* simple_distributed_example.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = simple_distributed_example.cpp; sourceTree = "<group>"; };
08668C4F0C19A16300ACB19A /* Jamfile.v2 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Jamfile.v2; sourceTree = "<group>"; };
08B9D4190CC3D0790050F10B /* test_binary_op.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = test_binary_op.cpp; sourceTree = "<group>"; };
@@ -157,10 +161,12 @@
08F2464E0CA86D85001C3D41 /* Cone5.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Cone5.cxx; sourceTree = "<group>"; };
08F2464F0CA86D85001C3D41 /* Cone6.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Cone6.cxx; sourceTree = "<group>"; };
08F24D6E0CC4419F00FC4A0C /* test_keyed_port.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_keyed_port.cpp; sourceTree = "<group>"; };
+ 08F264780CEA9DE800DA01C9 /* distributed_example.qbk */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = distributed_example.qbk; sourceTree = "<group>"; };
+ 08F264790CEA9DE800DA01C9 /* gil_example.qbk */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = gil_example.qbk; sourceTree = "<group>"; };
+ 08F2647A0CEA9DE800DA01C9 /* vtk_example.qbk */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = vtk_example.qbk; sourceTree = "<group>"; };
08F26C8B0CBF1CBA00EDC3F6 /* test_port.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_port.cpp; sourceTree = "<group>"; };
08F26D630CBF2D4100EDC3F6 /* test_proxy_port.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_proxy_port.cpp; sourceTree = "<group>"; };
- 08F2C31A0CAD961F00F9100C /* operators.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = operators.hpp; sourceTree = "<group>"; };
- 08F2C31B0CAD961F00F9100C /* support.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = support.hpp; sourceTree = "<group>"; };
+ 08F2C31B0CAD961F00F9100C /* vtk_dataflow_support.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = vtk_dataflow_support.hpp; sourceTree = "<group>"; };
08F2D3A90CCADDE00042A3FF /* underlying_type.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = underlying_type.hpp; sourceTree = "<group>"; };
08F348510C492B4B0096097F /* group.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = group.hpp; sourceTree = "<group>"; };
08F348970CC021E0006D0A67 /* copy_cv.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = copy_cv.hpp; sourceTree = "<group>"; };
@@ -218,8 +224,7 @@
0800AC2F0C8CA99700994538 /* VTK */ = {
isa = PBXGroup;
children = (
- 08F2C31A0CAD961F00F9100C /* operators.hpp */,
- 08F2C31B0CAD961F00F9100C /* support.hpp */,
+ 08F2C31B0CAD961F00F9100C /* vtk_dataflow_support.hpp */,
08F2464B0CA86D85001C3D41 /* Cone2.cxx */,
08F2464C0CA86D85001C3D41 /* Cone3.cxx */,
08F2464D0CA86D85001C3D41 /* Cone4.cxx */,
@@ -269,6 +274,7 @@
08C675960C13A03E00D85379 /* test */ = {
isa = PBXGroup;
children = (
+ 084467150CE790B300B3CFDF /* test_reflective_component.cpp */,
08B9D4190CC3D0790050F10B /* test_binary_op.cpp */,
08F71D3D0CA3547C0010099E /* signals */,
08C675970C13A03E00D85379 /* Jamfile.v2 */,
@@ -386,6 +392,7 @@
08061C980CBEF0C6002DC710 /* keyed_port.hpp */,
08F21FAD0CC6ABCF00DE649A /* component.hpp */,
08F21FB90CC6B29600DE649A /* component_operation.hpp */,
+ 0844671B0CE7918C00B3CFDF /* reflective_component.hpp */,
);
path = support;
sourceTree = "<group>";
@@ -414,6 +421,7 @@
isa = PBXGroup;
children = (
08F3944C0CCEC35E00ED7978 /* binary_operation.hpp */,
+ 0801B4370CE9488B00A7A8D1 /* operator.hpp */,
);
path = templates;
sourceTree = "<group>";
@@ -443,6 +451,16 @@
path = connection;
sourceTree = "<group>";
};
+ 08F264770CEA9DE800DA01C9 /* introduction */ = {
+ isa = PBXGroup;
+ children = (
+ 08F264780CEA9DE800DA01C9 /* distributed_example.qbk */,
+ 08F264790CEA9DE800DA01C9 /* gil_example.qbk */,
+ 08F2647A0CEA9DE800DA01C9 /* vtk_example.qbk */,
+ );
+ path = introduction;
+ sourceTree = "<group>";
+ };
08F348500C492B320096097F /* operator */ = {
isa = PBXGroup;
children = (
@@ -504,6 +522,7 @@
08668C4E0C19A16300ACB19A /* simple_distributed_example.cpp */,
08F98B400CD0190A009D642B /* Jamfile.v2 */,
08F98B470CD01963009D642B /* intro_example.cpp */,
+ 084D2E6E0CE7DFE900E861FA /* gil_example.cpp */,
);
path = signals;
sourceTree = "<group>";
@@ -567,6 +586,7 @@
08FD5DE40C1BA60700F00877 /* doc */ = {
isa = PBXGroup;
children = (
+ 08F264770CEA9DE800DA01C9 /* introduction */,
08F034B60CCBFA95009A4C8E /* port_concepts.qbk */,
083FD3C00C62A75100EF3F6B /* phoenix */,
08FB7BEE0C6157AE00BD4EC2 /* signals */,
Modified: sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/concepts.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -63,9 +63,12 @@
are accessible either through the class directly, or through its member
functions and variables.
+The Dataflow library also offers a [ComponentConcept] concept, which is
+intented to provide compile-time introspection and other operations.
+
[heading Proxies]
-It is often the case that a component delegates its [PortConcept]
+It is often the case that a port delegates its [PortConcept]
functionality to some other element. For example, a
class that is a [DataflowSignals] component might delegate its
[ProducerPortConcept] functionality to a member boost::signal. It can
@@ -253,7 +256,7 @@
[section ComponentTraits]
-A ['[ComponenTraitsConcept]] specifies the traits of a [ComponentConcept].
+A ['[ComponentTraitsConcept]] specifies the traits of a [ComponentConcept].
[heading Notation]
[variablelist
@@ -297,6 +300,8 @@
[heading Refinements]
+* [ReflectiveComponentConcept]
+
[heading Notation]
The following expressions are used in this document:
@@ -313,7 +318,7 @@
[`component_traits_of<M, C>::type`]
[Any [ComponentTraitsConcept] type]
[
- The [ComponentTraitsConcept] of the port.
+ The [ComponentTraitsConcept] of the component.
]
]
[
@@ -340,6 +345,70 @@
[endsect][/component]
+[section ReflectiveComponent]
+
+A [ComponentConcept] `C` for a mechanism `M` is a ['[ReflectiveComponentConcept]]
+if's [ComponentTraitsConcept] is a [ReflectiveComponentTraitsConcept], and it
+specializes the `get_component_port_impl` implementation to provide access
+to it's ports.
+
+[heading Refinement of]
+
+* [ComponentConcept]
+
+[heading Notation]
+The following expressions are used in this document:
+
+[variablelist
+ [[C] [A ReflectiveComponent type.]]
+ [[M] [A [MechanismConcept] type.]]
+ [[I] [An MPL Integral Constant in the range 0, n of ports exposed by C.]]
+ [[c] [An object of type C.]]
+]
+
+[heading Requirements]
+[table
+ [[Name] [Expression] [Result Type] [Semantics]]
+ [
+ [Component Traits]
+ [`component_traits_of<M, C>::type`]
+ [Any [ReflectiveComponentTraitsConcept] type]
+ [
+ The [ReflectiveComponentTraitsConcept] of the component.
+ ]
+ ]
+ [
+ [IsReflectiveComponent Trait]
+ [`is_reflective_component<M, C>::type`]
+ [Boolean metafunction that evaluates to true]
+ [
+ A trait encapsulating adherence to the ReflectiveComponent
+ concept.
+ ]
+ ]
+ [
+ [ GetComponentPort ]
+ [`get_component_port<M, I>(c)`]
+ []
+ [
+ Returns the I'th [PortConcept] exposed by `C`
+ ]
+ ]
+]
+
+[heading Header]
+
+```
+ #include <boost/dataflow/support/component.hpp> // or
+ #include <boost/dataflow/support.hpp>
+```
+
+[heading Notes]
+
+[heading Examples]
+
+[endsect][/component]
+
[section:componentoperable ComponentOperable (Invocable) ]
Modified: sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/dataflow.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -1,6 +1,6 @@
[article Dataflow
[quickbook 1.4]
- [version 0.8.0]
+ [version 0.8.1]
[authors [Rajko, Stjepan]]
[copyright 2007 Stjepan Rajko]
[purpose Generic dataflow lirary providing support for data producers,
@@ -25,6 +25,8 @@
[template ComponentTraitsConcept[] [link dataflow.concepts.componenttraits [^ComponentTraits]]]
[template ComponentConcept[] [link dataflow.concepts.component [^Component]]]
+[template ReflectiveComponentTraitsConcept[] [link dataflow.concepts.reflecivecomponenttraits [^ReflectiveComponentTraits]]]
+[template ReflectiveComponentConcept[] [link dataflow.concepts.reflectivecomponent [^ReflectiveComponent]]]
[template BinaryOperableConcept[] [link dataflow.concepts.binaryoperable [^BinaryOperable]]]
[template ConnectableConcept[] [link dataflow.concepts.binaryoperable [^Connectable]]]
@@ -98,6 +100,8 @@
[template blueprint[] [link dataflow.future.blueprint blueprint]]
+[import ../test/test_port.cpp]
+
[import ../test/signals/test_connect.cpp]
[import ../test/signals/test_branching.cpp]
[import ../test/signals/test_pull.cpp]
@@ -122,8 +126,10 @@
[import ../example/signals/simple_example.cpp]
[import ../example/signals/simple_distributed_example.cpp]
[import ../example/signals/intro_example.cpp]
+[import ../example/signals/gil_example.cpp]
-[import ../example/VTK/support.hpp]
+[import ../example/VTK/vtk_dataflow_support.hpp]
+[import ../example/VTK/Cone.cxx]
[include introduction.qbk]
Modified: sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -188,7 +188,7 @@
* The [DataflowSignals] layer, with a number of implemented components that
facilitate implementation of dataflow networks using [BoostSignals] as
a data transport mechanism.
-
+
There is also a (currently very experimental) [DataflowPhoenix] layer,
which uses object pointers with support for
[BoostPhoenix] actors specifying how the data is processed.
@@ -336,271 +336,10 @@
[endsect][/how_to_use]
[section Examples]
-[section:new_layer Implementing support for a new mechanism (VTK)]
-
-This example shows how to implement support for a particular mechanism.
-Our victim is [VTK], a 3D visualization toolkit, which uses a data pipeline
-to move data from a source to the display (with possible transformations,
-scene construction etc. on the way). For example, here is an excerpt from
-a VTK tutorial that sets up a whole source->render window pipeline:
-
-```
- // allocate components
- vtkConeSource *cone = vtkConeSource::New();
- vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
- vtkActor *coneActor = vtkActor::New();
- vtkRenderer *ren1= vtkRenderer::New();
- vtkRenderWindow *renWin = vtkRenderWindow::New();
-
- // make the connections
- coneMapper->SetInputConnection( cone->GetOutputPort() );
- coneActor->SetMapper( coneMapper );
- ren1->AddActor( coneActor );
- renWin->AddRenderer( ren1 );
-```
-
-Our goal will be to simplify the connection-making code by providing
-Dataflow support for VTK. With that in place, we will be able to use the
-following connection code:
-
-```
- // make the connections
- connect(cone, coneMapper);
- connect(coneMapper, coneActor);
- connect(coneActor, ren1);
- connect(ren1, renWin);
-```
-
-or even more concisely and clearly,
-
-```
- // make the connections
- // C++ rules prevent us from removing all of the pointer dereferencing here
- *cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= *renWin;
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.mechanism
- Setting up the Mechanism]
-
-[section:mechanism Setting up the Mechanism]
-
-The first thing we'll do is create a tag for the VTK [MechanismConcept], in
-namespace `boost::dataflow::vtk`. Since there are currently no requirements
-for a [MechanismConcept], this is as simple as declaring a new type to be used
-as the mechanism tag:
-
-[vtk_mechanism]
-
-We will now use this tag in reference to the [VTK] dataflow mechanism.
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.producerconsumer
- Setting up a ProducerPort and ConsumerPort]
-[endsect][/mechanism]
-
-[section:producerconsumer Setting up a ProducerPort and ConsumerPort]
-
-Now that we have the mechanism, let's cover the basic data pipeline,
-which is implemented using the
-[vtkAlgorithm] class. This class provides input and output ports. Output ports
-are accessible via `GetOuptutPort` member functions, which return a proxy
-object ([vtkAlgorithmOutput] `*`) for an actual output port.
-
-In Dataflow concepts, [vtkAlgorithmOutput] can be made a [ProducerPortConcept]
-- it corresponds to a single data output point. We support it as such by
-defining a [PortTraitsConcept] type, and associating it with
-[vtkAlgorithmOutput].
-
-[vtk_algorithm_output_producer]
-
-Now that we have a [ProducerPortConcept], we need a [ConsumerPortConcept].
-[vtkAlgorithm] can accept incoming connections using the `AddInputConnection`
-and `SetInputConnection` member functions. The code below provides support
-for [vtkAlgorithm] accepting connections on its default input port:
-
-[vtk_algorithm_consumer]
-
-[heading Next]
-
-[link dataflow.introduction.examples.new_layer.connectable
- Making things Connectable]
-
-[endsect][/producerconsumer]
-
-[section:connectable Making things Connectable]
-
-With the pair of [ProducerPortConcept] and [ConsumerPortConcept] registered, we
-can make them [ConnectableConcept] and/or [OnlyConnectableConcept].
-All we need to do is specialize the implementation for the appropriate
-[PortTraits]:
-
-[vtk_connect_impl_algorithm]
-
-Connections are done through the `boost::dataflow::binary_operation` function
-with either `operation::connect` or `operation::connect_only` operation tag,
-and the specified mechanism. To make connecting
-easier, we'll add forwarding connect and connect_only
-functions in the global namespace (where vtk classes live) specific
-to the vtk mechanism using the template include files for this purpose:
-
-[vtk_specialize_connect]
-
-[heading What we can do with what we have so far]
-
-```
- // connect *cone to *coneMapper
- connect(*cone->GetOutputPort(), *coneMapper);
- // make *cone the only thing connected to *coneMapper
- connect_only(*cone->GetOutputPort(), *coneMapper);
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.proxyproducer
- Setting up a ProxyProducer]
-
-[endsect][/connectable]
-
-[section:proxyproducer Setting up a ProxyPort]
-
-In the VTK example above, both `vtkConeSource` and `vtkPolyDataMapper`
-inherit [vtkAlgorithm].
-With the [vtkAlgorithmOutput] [ProducerPortConcept] and
-[vtkAlgorithm] [ConsumerPortConcept] we've set up,
-we can do things like `connect(cone->GetOutputPort(), *coneMapper);`.
-However, we would like to do `connect(*cone, *coneMapper)`.
-
-To do that,
-we need to make [vtkAlgorithm] a [ProducerPortConcept]. Since [vtkAlgorithm]
-forms its output connections using [vtkAlgorithmOutput] objects
-returned through the `GetOutputPort` member functions, and we've already
-configured [vtkAlgorithmOutput] as a [ProducerPortConcept], we can make use
-of the [ProxyPortConcept] concept provided by the dataflow library.
-In effect, we will make [vtkAlgorithm] delegate it's [ProducerPortConcept]
-functionality to [vtkAlgorithmOutput]:
-
-[vtk_algorithm_proxy_producer]
-
-Now, [vtkAlgorithm] is a [ProducerPortConcept].
-
-[heading What we can do with what we have so far]
-
-```
- connect(*cone, *coneMapper)
-```
-[heading Next]
-[link dataflow.introduction.examples.new_layer.filter
- Setting up a filter (ProducerPort+ConsumerPort)]
-
-[endsect][/proxyproducer]
-
-[section:filter Setting up a Filter (Producer+Consumer)]
-
-In a VTK pipeline, a [vtkActor] consumes data from a [vtkMapper], and produces
-data for a [vtkRenderer]. In this case, we can provide Dataflow support
-for a [vtkActor] as both a [ProducerPortConcept] and a [ConsumerPortConcept]:
-
-[vtk_actor_filter]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.producermap
- Setting up a KeyedPort]
-
-[endsect][/filter]
-
-[section:producermap Setting up a KeyedPort]
-
-Sometimes, components can produce (or consume) multiple types of data.
-For example, [vtkMapper] objects can produce data for [vtkActor] objects,
-or (since [vtkMapper] inherits [vtkAlgorithm]) for other [vtkAlgorithm]
-objects. Correspondingly, connecting a [vtkMapper] to a [vtkActor] is not
-the same as connecting a [vtkMapper] to another [vtkAlgorithm].
-
-To accomodate such situations, the Dataflow library provides
-[KeyedPortConcept]s, which are similar to [ProxyPortConcept]s but
-the [PortConcept] they delegate to is keyed on the
-[PortConcept] they are being connected to.
-
-[vtk_mapper_producer]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.remaining
- Setting up the remaining components (more of the same)]
-
-[endsect][/producermap]
-
-[section:remaining Setting up the remaining components (more of the same)]
-
-[vtk_setup_rest]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.pointers
- Supporting pointers]
-
-[endsect][/remaining]
-
-[section:pointers Supporting pointers]
-
-All of the concepts we adapted so far have been adapted for class types such
-as [vtkAlgorithm] and [vtkAlgorithmOutput]. But [VTK] seems to exclusively
-use pointers to class types rather than class types themselves. So, with what
-we have done so far, we can do `connect(*cone, *coneMapper)` but not
-`connect(cone, coneMapper)`. To provide support for pointers, we
-simply make them adhere to the [ProxyPortConcept] concept, and delegate the
-functionality to the object they point to.
-
-[vtk_support_pointer]
-
-[endsect][/pointers]
-
-
-
-[endsect][/new_layer]
-
-[section:distributed Implementing distributed dataflow applications using
- Dataflow.Signals and Boost.Asio]
-
-This example shows how you can take advantage of dataflow programming
-to create distributed applications. It works as long as the data
-passed in the signal is serializable using [BoostSerialization].
-
-[DataflowSignals] provides two components
-which can be used to create a producer-consumer connection between two
-computers: [socket_sender] and [socket_receiver]. As long as we have
-a network socket set up between two computers, we can do the following to
-set up a connection between a [SignalProducerConcept] on one computer with a
-[SignalConsumerConcept] on another:
-
-* On the [SignalProducerConcept]'s computer, construct a [socket_sender] of
-the appropriate `Signature` with the given socket.
-[connect] the [SignalProducerConcept] to the [socket_sender].
-* On the [SignalConsumerConcept]'s computer, construct a [socket_receiver] of
-the appropriate `Signature` with the given socket.
-[connect] the [socket_receiver] to the [SignalConsumerConcept].
-
-That's it. Now, every signal sent out of the [SignalProducerConcept] should
-be received by the [SignalConsumerConcept].
-
-The following is a modification of the example from the
-[link dataflow.introduction.dataflow motivation section] to a dataflow
-network that straddles a network socket:
-
-[simple_distributed_example]
-
-A sample run produces:
-
-[pre
-0.213436
--0.49558
-1.57538
--1.0592
-1.83927
-1.88577
-...
-]
-
-[endsect][/distributed]
+[include introduction/distributed_example.qbk]
+[include introduction/gil_example.qbk]
+[include introduction/vtk_example.qbk]
[endsect][/examples]
@@ -612,6 +351,15 @@
latest version is located in the
[@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/signals Boost sandbox].
+The Dataflow library uses the trunk version of Boost - it might not work
+perfectly with release versions of boost.
+
+Version 0.8.1 (under construction)
+
+* expanding the [ComponentConcept] concept.
+* making VTK example Jamfile work for more than Darwin and X11.
+* provided an example using Boost.GIL.
+
Version 0.8.0 -
\[[@http://www.boost-consulting.com/vault/index.php?direction=&order=&directory=Dataflow& available in the Boost vault]\]
@@ -645,6 +393,9 @@
to build each one of those by going to the appropriate directory and
running bjam.
+[warning The Jamfile for the VTK examples currently only works for Darwin
+and for VTK built for X]
+
The library itself is header only, and requires no linking. However, parts
of it depend on boost libraries which do need to be built and linked (see
the linking information below).
Copied: sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/distributed_example.qbk (from r41018, /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk)
==============================================================================
--- /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/distributed_example.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -1,563 +1,3 @@
-[section:introduction Introduction]
-
-Dataflow is a generic library for [WikiDataflow] programming using various data
-transport mechanisms. It also has layers of support for
-two data transport mechanisms - one is based on
-[BoostSignals], and the other (experimental and currently broken) is based
-connections made through
-simple object pointers, with support for using [BoostPhoenix2]
-actors for data processing.
-
-The two data transport mechanisms are implemented in the [DataflowSignals]
-and [DataflowPhoenix] layers. The idea behind providing a generic dataflow
-library is that other data transport mechanisms can be easily adapted for
-use with the library.
-
-[warning Dataflow is not a part of the Boost libraries. It is being developed
-as a part of the Google Summer of Code program. The original proposal (for
-the Signal Network library, which became the Dataflow library)
-as well as some status updates can be found on the
-[@http://svn.boost.org/trac/boost/wiki/soc/2007/SignalNetwork GSoC page].]
-
-* If you would like some more information about why one would want to connect
- objects into a dataflow network, read about
- [link dataflow.introduction.dataflow Dataflow programming in C++].
-* If you'd like to try out the library
- * keep in mind that the interface is subject to change
- * Read [how_to_use how to use this library and the documentation].
-
-
-[section:dataflow Dataflow programming in C++ - motivation and advantages]
-
-The [WikiDataflow] programming paradigm is based on interconnected
-/components/ which process passing /data/. Basically, data is treated
-as something that originates from a source, flows through a number of
-processing components that manipulate it (e.g., by changing it,
-duplicating, etc.), and arrives at some final destination. As such,
-the dataflow paradigm is most suitable when developing applications that
-are themselves focused on the "flow" of data.
-
-Perhaps the most readily available examples of a
-dataflow-oriented applications come from the realm of real-time
-[@http://en.wikipedia.org/wiki/Signal_processing signal processing],
-e.g. a video signal processor which perhaps starts with a video input,
-modifies it through a number of processing components (video filters),
-and finally outputs it to a video display. Another example is event
-processing.
-
-[heading A motivating example]
-
-Let's take a simple real-time camera-input-displayed-on-the-screen application.
-Suppose there are three parts to the application - getting each image frame
-from the camera, processing the image in some way,
-and displaying it on the screen. To see how we might arrive at
-a dataflow-oriented implementation of this application,
-let's first begin with an imperative approach. Such an implementation might
-be structured as follows:
-
-[$dataflow1.png]
-
-Basically, the main program loop is a series of instructions which does
-this particular job. To take this a step further in the dataflow direction,
-we note that video input libraries often provide callback
-functionality which will deliver a video stream as a sequence of
-image frames given at the appropriate frame rate.
-With this in mind, we do the following:
-
-# implement a function which takes an image as input.
- # the function first invokes the image processing library function that
- modifies the image as appropriate
- # the function then invokes the GUI library function that displays the image
-# register the function as a callback with the camera library
-# the main program loop can relax and have some coffee.
-
-The situation now looks something like this:
-
-[$dataflow2.png]
-
-So now, the image library is acting as a data/signal producer - it
-generates images at a certain frame rate. And the function we
-implemented seems to be a signal consumer which can take an image,
-process it, and display it on the screen.
-
-This now employs the basic elements of the dataflow paradigm, but we could
-take it even further. Instead of just having two components, one image
-signal generator and one signal consumer, how about this:
-
-# implement a component which accepts an input image signal,
- modifies the image as appropriate, and then outputs
- a signal with the modified image
-# implement a component which receives an imput image signal and displays
- it on the screen
-# connect the camera library input stream to the first component
-# connect the first component to the second component
-# the main program loop can relax and have some tea, or even take a nap.
-
-The big picture now looks like the following:
-
-[$dataflow3.png]
-
-To give you a sense of how you would do something like this using the Dataflow
-library, we will present a slightly simplified example using [DataflowSignals].
-Instead of processing images, we will just process numbers - but the dataflow
-parts of the code are pretty much the same.
-
-We will first define a few components to use for our network:
-
-[simple_example_components]
-
-And then connect them in a dataflow network:
-
-[simple_example]
-
-A sample run produces:
-
-[pre
-
-0.213436
--0.49558
-1.57538
--1.0592
-1.83927
-1.88577
-0.604675
-...
-
-]
-
-...not quite image processing, but you get the (dataflow) point :-)
-
-[heading Advantages]
-
-There are already many programming paradigms supported by C++ (either directly or through
-additional libraries), so let's examine what the advantages of the the dataflow paradigm might be.
-
-First of all, [*dataflow programming is not exclusive of other paradigms], so adopting the dataflow paradigm
-does not hinder the use of other techniques. In fact, in C++ it can't - since the components
-themselves need to be implemented somehow, and we can't recursively define them
-forever as finer and finer dataflow diagrams, the dataflow paradigm relies on other
-programming techniques to do the underlying work. Also, dataflow does not need
-be used for the entire application implementation. You can always use it
-for only those parts of the application it is appropriate for, and
-"extend your fingers" from other parts of the program in order
-to insert data into the dataflow, catch it on the other end, probe and adjust the components, etc.
-You can think of it as working with electronic components and changing the connections, turning knobs,
-flipping switches, or hanging over a circuit board and tinkering with it using, say, a multimeter and a
-5V lead (just do it with care).
-
-Second, [*dataflow promotes some good programming practices]. When developing processing components,
-we have only the incoming data to deal with - with no requirements on where it is coming from. Hence,
-the developed components tend to be quite versatile and reusable. In the above example, the image
-processing component can be used with any image data generator - there is nothing inside the component
-that says "get the image from the camera", or "get the image from this type of data source (where the
-type is either a base class or a concept)". It just does it's thing, no matter where the data is coming
-from.
-
-Third, when used in the right context, [*dataflow programming makes development and maintenance
-very intuitive]. In the image processing example, say you don't want to process the image any more. You can
-just connect the camera signal directly to the screen display and cut out
-the image processing component. Someone gives you a new video signal generator component you'd like to use as input
-instead of the camera? Just plug it in. Literally.
-
-Fourth, [*dataflow-oriented programs can be divided between threads, processors, or computers more easily],
-because the data dependencies are much more visible. In the image processing example, say you have
-the display on a different computer. You can just pass the connection to it through a network socket.
-With the data flow clearly specified, it is much easier to distribute the work either manually or
-even automatically (although the Dataflow library at the moment offers no such automatic functionality).
-
-Finally, [*we are not to far from the advantages of a [@http://en.wikipedia.org/wiki/Visual_programming_language
-visual programming language]], since the components and the connections have a natural graphical representation.
-With a visaul development environment, programming becomes as easy as connecting components with connections
-(again, the Dataflow library provides no visual programming functionality).
-
-[heading Go with the flow?]
-
-If you are interested in exploring the dataflow concept further using
-the Dataflow library, see
-
-* [how_to_use How to use this library and the documentation].
-
-[endsect][/dataflow]
-
-[section:how_to_use How to use this library and the documentation]
-
-The Dataflow library currently has two useful parts:
-
-* A layer providing generic dataflow support, adaptable to various dataflow
- mechanisms.
-* The [DataflowSignals] layer, with a number of implemented components that
- facilitate implementation of dataflow networks using [BoostSignals] as
- a data transport mechanism.
-
-There is also a (currently very experimental) [DataflowPhoenix] layer,
-which uses object pointers with support for
-[BoostPhoenix] actors specifying how the data is processed.
-
-[heading Generic dataflow layer]
-
-There are generic properties of dataflow programs which do not depend on the
-data transport mechanism,
-and can be exploited to develop mechanism-independent dataflow code.
-The generic dataflow layer captures some of these properties, and
-has been sucessfully adapted to three
-different data transport mechanisms ([BoostSignals], pointers in conjunction
-with [BoostPhoenix2], and [VTK] pipelines).
-
-Currently, the most useful functionality gained by developing a Dataflow
-support layer is the ability to connect components in a clean, readable
-manner. As more generic code is developed on top of
-the generic dataflow layer, providing a Dataflow support layer for your
-favorite data transport mechanism will be more beneficial.
-
-See the [link dataflow.future future directions] of the Dataflow library
-for an idea of what might become available in the future for data transport
-mechanisms with Dataflow library support.
-
-* If you would like to implement Dataflow support for the data transport
-mechanism you are working with, see the
-[link dataflow.introduction.examples.new_layer example] showing
-how the [VTK] support layer was developed.
-* If you are interested in developing generic code on top of the dataflow
-layer, see the [concepts] documentation.
-
-[heading Dataflow.Signals layer]
-
-This part of the Dataflow library provides components
-and connection-making capabilty which facilitates large-scale use of
-Boost.Signals as a mechanism to transfer data between processing components.
-
-For examples of how the [DataflowSignals] layer can be used, see:
-
-* The example on developing a
- [link dataflow.introduction.examples.distributed distributed dataflow application].
-* The [DataflowSignals] documentation.
-
-[/[heading When to use]
-
-While the [link dataflow.introduction.dataflow dataflow] section hopefully
-convinced you that there are circumstances in which a dataflow approach is
-useful, please keep in mind that there are many circumstances in which this
-is not the case.
-
-First, a dataflow approach really only makes sense when the underlying task is
-really about the flow of data through the components that process it.
-If you can't sketch a concise data flow diagram which truly represents
-the application, the dataflow approach might not be the best option.
-For example, if you are implementing a complicated algorithm which is really
-about the sequence of instructions that need to be executed on the data
-(rather than the data going through well-defined and self-contained
-processing components), you probably should't use the Dataflow library.
-If you are working on an audio or video processing application,
-maybe you should.
-
-Second, the data transport mechanism you choose should reflect the needs of
-the applications closely. Most of the functionality that the library supports
-at this moment is regarding run-time configurable connections. If you don't
-need that functionality, you might be wasting resources ([DataflowPhoenix]
-offers some functionality related to compile-time connectability in its
-iterator_relative connections, but that is yet to trickle out into the library
-as a whole).
-
-When using signals as the data transport mechanism, remember that every signal
-sent results in a function call, and if the processing
-components are so minute that the cost of the function
-calls overtakes the cost of the processing,
-using [DataflowSignals] will cause a significant performance hit. A similar
-situation occurs with [DataflowPhoenix], where each consumer must be invoked.
-
-To sum up, consider using the Dataflow library when:
-
-* The application can be modeled well through the flow of data; and
-* The cost of the processing shadows the cost of the function calls, and any
- unnecessary overhead caused by any connections that need to be stored.
-]
-
-
-[/[heading Dataflow library organization]
-
-The design of the Dataflow library looks like this:
-
-[xinclude dataflow_table.xml]
-
-The layers are a bottom-up hierarchy, with dependencies
-only on layers underneath.
-The /support/ layer provides the necessary generic traits and functions
-required for generic code to work with mechanism-specific
-components. Each type of mechanism or component must specialize the elements
-of the support layer to work with the mechanism\/component.
-
-Directly based on the support layer, we have functions like /connect/ and
-/invoke/, which can be used to manipulate generic and mechanism-specific
-components that the library supports. /Operators/ are based on /connect/.
-
-
-The library also offers a few generic components, which can be used
-to group other components together: [producer_group], [consumer_group],
-and [consumer_map].
-
-The rest of the library is in the mechanism-specific modules [DataflowSignals]
-and [DataflowPhoenix], each of which provide their own support layer, on
-top of which their components are implemented.
-
-As long as the support layer is implemented
-for the mechanism/component, the component should
-work seamlesly with the rest of the dataflow library.
-Essentially, the support layer is a very minimal layer implementing a generic
-and extensible intrusive directed graph framework.
-
-[heading Namespace use]
-
-Since the Dataflow library provides both a generic layer, as well as
-mechanism-specific implementations, its elements are scattered over multiple
-namespaces.
-
-The fundamental user-oriented generic elements, such as `is_producer`,
-`producer_category_of` etc., are located in the `boost::dataflow` namespace.
-Function objects which must be specialized for different data transport
-mechanisms, such as `connect_impl`, are in the `boost::dataflow::extension`
-namespace. The connection operators are in `boost::dataflow::operators`.
-
-On the other hand, individual data transport mechanism implementations
-are located in the namespace of the data transport mechanism. For example,
-all of the [DataflowSignals] components are in the `boost::signals` namespace,
-and all of the [DataflowPhoenix] components are in the `boost::phoenix`
-namespace. Furthermore, free functions such as `connect` and `invoke` are
-imported into the mechanism's namespace, so that they can be used via ADL.
-
-All of the examples shown in this documentation are assuming the use of
-
- using namespace boost;
-
-[note Since there are multiple namespaces used, the documentation will
-explicitly state the namespace of documented elements wherever it is
-convenient.]
-]
-
-[endsect][/how_to_use]
-
-[section Examples]
-[section:new_layer Implementing support for a new mechanism (VTK)]
-
-This example shows how to implement support for a particular mechanism.
-Our victim is [VTK], a 3D visualization toolkit, which uses a data pipeline
-to move data from a source to the display (with possible transformations,
-scene construction etc. on the way). For example, here is an excerpt from
-a VTK tutorial that sets up a whole source->render window pipeline:
-
-```
- // allocate components
- vtkConeSource *cone = vtkConeSource::New();
- vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
- vtkActor *coneActor = vtkActor::New();
- vtkRenderer *ren1= vtkRenderer::New();
- vtkRenderWindow *renWin = vtkRenderWindow::New();
-
- // make the connections
- coneMapper->SetInputConnection( cone->GetOutputPort() );
- coneActor->SetMapper( coneMapper );
- ren1->AddActor( coneActor );
- renWin->AddRenderer( ren1 );
-```
-
-Our goal will be to simplify the connection-making code by providing
-Dataflow support for VTK. With that in place, we will be able to use the
-following connection code:
-
-```
- // make the connections
- connect(cone, coneMapper);
- connect(coneMapper, coneActor);
- connect(coneActor, ren1);
- connect(ren1, renWin);
-```
-
-or even more concisely and clearly,
-
-```
- // make the connections
- // C++ rules prevent us from removing all of the pointer dereferencing here
- *cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= *renWin;
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.mechanism
- Setting up the Mechanism]
-
-[section:mechanism Setting up the Mechanism]
-
-The first thing we'll do is create a tag for the VTK [MechanismConcept], in
-namespace `boost::dataflow::vtk`. Since there are currently no requirements
-for a [MechanismConcept], this is as simple as declaring a new type to be used
-as the mechanism tag:
-
-[vtk_mechanism]
-
-We will now use this tag in reference to the [VTK] dataflow mechanism.
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.producerconsumer
- Setting up a ProducerPort and ConsumerPort]
-[endsect][/mechanism]
-
-[section:producerconsumer Setting up a ProducerPort and ConsumerPort]
-
-Now that we have the mechanism, let's cover the basic data pipeline,
-which is implemented using the
-[vtkAlgorithm] class. This class provides input and output ports. Output ports
-are accessible via `GetOuptutPort` member functions, which return a proxy
-object ([vtkAlgorithmOutput] `*`) for an actual output port.
-
-In Dataflow concepts, [vtkAlgorithmOutput] can be made a [ProducerPortConcept]
-- it corresponds to a single data output point. We support it as such by
-defining a [PortTraitsConcept] type, and associating it with
-[vtkAlgorithmOutput].
-
-[vtk_algorithm_output_producer]
-
-Now that we have a [ProducerPortConcept], we need a [ConsumerPortConcept].
-[vtkAlgorithm] can accept incoming connections using the `AddInputConnection`
-and `SetInputConnection` member functions. The code below provides support
-for [vtkAlgorithm] accepting connections on its default input port:
-
-[vtk_algorithm_consumer]
-
-[heading Next]
-
-[link dataflow.introduction.examples.new_layer.connectable
- Making things Connectable]
-
-[endsect][/producerconsumer]
-
-[section:connectable Making things Connectable]
-
-With the pair of [ProducerPortConcept] and [ConsumerPortConcept] registered, we
-can make them [ConnectableConcept] and/or [OnlyConnectableConcept].
-All we need to do is specialize the implementation for the appropriate
-[PortTraits]:
-
-[vtk_connect_impl_algorithm]
-
-Connections are done through the `boost::dataflow::binary_operation` function
-with either `operation::connect` or `operation::connect_only` operation tag,
-and the specified mechanism. To make connecting
-easier, we'll add forwarding connect and connect_only
-functions in the global namespace (where vtk classes live) specific
-to the vtk mechanism using the template include files for this purpose:
-
-[vtk_specialize_connect]
-
-[heading What we can do with what we have so far]
-
-```
- // connect *cone to *coneMapper
- connect(*cone->GetOutputPort(), *coneMapper);
- // make *cone the only thing connected to *coneMapper
- connect_only(*cone->GetOutputPort(), *coneMapper);
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.proxyproducer
- Setting up a ProxyProducer]
-
-[endsect][/connectable]
-
-[section:proxyproducer Setting up a ProxyPort]
-
-In the VTK example above, both `vtkConeSource` and `vtkPolyDataMapper`
-inherit [vtkAlgorithm].
-With the [vtkAlgorithmOutput] [ProducerPortConcept] and
-[vtkAlgorithm] [ConsumerPortConcept] we've set up,
-we can do things like `connect(cone->GetOutputPort(), *coneMapper);`.
-However, we would like to do `connect(*cone, *coneMapper)`.
-
-To do that,
-we need to make [vtkAlgorithm] a [ProducerPortConcept]. Since [vtkAlgorithm]
-forms its output connections using [vtkAlgorithmOutput] objects
-returned through the `GetOutputPort` member functions, and we've already
-configured [vtkAlgorithmOutput] as a [ProducerPortConcept], we can make use
-of the [ProxyPortConcept] concept provided by the dataflow library.
-In effect, we will make [vtkAlgorithm] delegate it's [ProducerPortConcept]
-functionality to [vtkAlgorithmOutput]:
-
-[vtk_algorithm_proxy_producer]
-
-Now, [vtkAlgorithm] is a [ProducerPortConcept].
-
-[heading What we can do with what we have so far]
-
-```
- connect(*cone, *coneMapper)
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.filter
- Setting up a filter (ProducerPort+ConsumerPort)]
-
-[endsect][/proxyproducer]
-
-[section:filter Setting up a Filter (Producer+Consumer)]
-
-In a VTK pipeline, a [vtkActor] consumes data from a [vtkMapper], and produces
-data for a [vtkRenderer]. In this case, we can provide Dataflow support
-for a [vtkActor] as both a [ProducerPortConcept] and a [ConsumerPortConcept]:
-
-[vtk_actor_filter]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.producermap
- Setting up a KeyedPort]
-
-[endsect][/filter]
-
-[section:producermap Setting up a KeyedPort]
-
-Sometimes, components can produce (or consume) multiple types of data.
-For example, [vtkMapper] objects can produce data for [vtkActor] objects,
-or (since [vtkMapper] inherits [vtkAlgorithm]) for other [vtkAlgorithm]
-objects. Correspondingly, connecting a [vtkMapper] to a [vtkActor] is not
-the same as connecting a [vtkMapper] to another [vtkAlgorithm].
-
-To accomodate such situations, the Dataflow library provides
-[KeyedPortConcept]s, which are similar to [ProxyPortConcept]s but
-the [PortConcept] they delegate to is keyed on the
-[PortConcept] they are being connected to.
-
-[vtk_mapper_producer]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.remaining
- Setting up the remaining components (more of the same)]
-
-[endsect][/producermap]
-
-[section:remaining Setting up the remaining components (more of the same)]
-
-[vtk_setup_rest]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.pointers
- Supporting pointers]
-
-[endsect][/remaining]
-
-[section:pointers Supporting pointers]
-
-All of the concepts we adapted so far have been adapted for class types such
-as [vtkAlgorithm] and [vtkAlgorithmOutput]. But [VTK] seems to exclusively
-use pointers to class types rather than class types themselves. So, with what
-we have done so far, we can do `connect(*cone, *coneMapper)` but not
-`connect(cone, coneMapper)`. To provide support for pointers, we
-simply make them adhere to the [ProxyPortConcept] concept, and delegate the
-functionality to the object they point to.
-
-[vtk_support_pointer]
-
-[endsect][/pointers]
-
-
-
-[endsect][/new_layer]
-
[section:distributed Implementing distributed dataflow applications using
Dataflow.Signals and Boost.Asio]
@@ -601,66 +41,3 @@
]
[endsect][/distributed]
-
-[endsect][/examples]
-
-[section:download Downloading, building and linking]
-
-[heading Downloading]
-
-I am currently preparing this library for submission for a Boost review. The
-latest version is located in the
-[@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/signals Boost sandbox].
-
-Version 0.8.0 -
- \[[@http://www.boost-consulting.com/vault/index.php?direction=&order=&directory=Dataflow& available in the Boost vault]\]
-
-* post-GSoC version
-* generic dataflow support layer with tests and examples
-* Dataflow.Signals layer (fusion-based implementation) with tests and examples
-* VTK example
-* quickbook docs
-
-[/Proposal for Boost / Google SoC version \[[@signal_network.zip download]\]
-
-* finished the signals::socket_sender and signals::socket_receiver components
-
-Draft proposal for Boost / Google SoC version
-
-* changed the file and namespace structure
-* implemented a file-iteration based mechanism for arity-dependent classes
-* changed the operators used
-* signal_link is now signals::filter and does not need to know it's descendant's type
-* implemented signals::junction, signals::selector, signals::storage, signals::timed_generator,
- signals::mutex, signals::chain, signals::function classes
-
-Original request for interest version available as attachment to
-[@http://lists.boost.org/Archives/boost/2007/02/116869.php]
-]
-
-[heading Building]
-
-The library comes with Boost.Build Jamfiles for all examples, tests, and docs.
-As long as your BOOST_ROOT environment variable is set, you should be able
-to build each one of those by going to the appropriate directory and
-running bjam.
-
-The library itself is header only, and requires no linking. However, parts
-of it depend on boost libraries which do need to be built and linked (see
-the linking information below).
-
-[heading Linking]
-
-The generic Dataflow support layer is header-only, and relies only on other
-Boost header-only libraries (MPL, enable_if, and small parts of fusion).
-
-The [DataflowSignals] layer is dependent on the [BoostSignals] library,
-which must be built and linked. A few of the components ([socket_sender]
-and [socket_receiver]) are also dependent on [BoostAsio], which depends on
-the System library which must also be built and linked. A few other components
-([mutex] and [condition]) are dependent on [BoostThread], which has to be
-linked as well.
-
-[endsect][/download]
-
-[endsect][/introduction]
Copied: sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/gil_example.qbk (from r41018, /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk)
==============================================================================
--- /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/gil_example.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -1,666 +1,202 @@
-[section:introduction Introduction]
+[section:gil An image processing network using Dataflow.Signals and Boost.GIL]
-Dataflow is a generic library for [WikiDataflow] programming using various data
-transport mechanisms. It also has layers of support for
-two data transport mechanisms - one is based on
-[BoostSignals], and the other (experimental and currently broken) is based
-connections made through
-simple object pointers, with support for using [BoostPhoenix2]
-actors for data processing.
-
-The two data transport mechanisms are implemented in the [DataflowSignals]
-and [DataflowPhoenix] layers. The idea behind providing a generic dataflow
-library is that other data transport mechanisms can be easily adapted for
-use with the library.
-
-[warning Dataflow is not a part of the Boost libraries. It is being developed
-as a part of the Google Summer of Code program. The original proposal (for
-the Signal Network library, which became the Dataflow library)
-as well as some status updates can be found on the
-[@http://svn.boost.org/trac/boost/wiki/soc/2007/SignalNetwork GSoC page].]
-
-* If you would like some more information about why one would want to connect
- objects into a dataflow network, read about
- [link dataflow.introduction.dataflow Dataflow programming in C++].
-* If you'd like to try out the library
- * keep in mind that the interface is subject to change
- * Read [how_to_use how to use this library and the documentation].
-
-
-[section:dataflow Dataflow programming in C++ - motivation and advantages]
-
-The [WikiDataflow] programming paradigm is based on interconnected
-/components/ which process passing /data/. Basically, data is treated
-as something that originates from a source, flows through a number of
-processing components that manipulate it (e.g., by changing it,
-duplicating, etc.), and arrives at some final destination. As such,
-the dataflow paradigm is most suitable when developing applications that
-are themselves focused on the "flow" of data.
-
-Perhaps the most readily available examples of a
-dataflow-oriented applications come from the realm of real-time
-[@http://en.wikipedia.org/wiki/Signal_processing signal processing],
-e.g. a video signal processor which perhaps starts with a video input,
-modifies it through a number of processing components (video filters),
-and finally outputs it to a video display. Another example is event
-processing.
-
-[heading A motivating example]
-
-Let's take a simple real-time camera-input-displayed-on-the-screen application.
-Suppose there are three parts to the application - getting each image frame
-from the camera, processing the image in some way,
-and displaying it on the screen. To see how we might arrive at
-a dataflow-oriented implementation of this application,
-let's first begin with an imperative approach. Such an implementation might
-be structured as follows:
-
-[$dataflow1.png]
-
-Basically, the main program loop is a series of instructions which does
-this particular job. To take this a step further in the dataflow direction,
-we note that video input libraries often provide callback
-functionality which will deliver a video stream as a sequence of
-image frames given at the appropriate frame rate.
-With this in mind, we do the following:
-
-# implement a function which takes an image as input.
- # the function first invokes the image processing library function that
- modifies the image as appropriate
- # the function then invokes the GUI library function that displays the image
-# register the function as a callback with the camera library
-# the main program loop can relax and have some coffee.
-
-The situation now looks something like this:
-
-[$dataflow2.png]
-
-So now, the image library is acting as a data/signal producer - it
-generates images at a certain frame rate. And the function we
-implemented seems to be a signal consumer which can take an image,
-process it, and display it on the screen.
-
-This now employs the basic elements of the dataflow paradigm, but we could
-take it even further. Instead of just having two components, one image
-signal generator and one signal consumer, how about this:
-
-# implement a component which accepts an input image signal,
- modifies the image as appropriate, and then outputs
- a signal with the modified image
-# implement a component which receives an imput image signal and displays
- it on the screen
-# connect the camera library input stream to the first component
-# connect the first component to the second component
-# the main program loop can relax and have some tea, or even take a nap.
-
-The big picture now looks like the following:
-
-[$dataflow3.png]
-
-To give you a sense of how you would do something like this using the Dataflow
-library, we will present a slightly simplified example using [DataflowSignals].
-Instead of processing images, we will just process numbers - but the dataflow
-parts of the code are pretty much the same.
-
-We will first define a few components to use for our network:
-
-[simple_example_components]
-
-And then connect them in a dataflow network:
-
-[simple_example]
-
-A sample run produces:
+The [link dataflow.introduction.motivation motivation] section introduced a
+hypothetical video processing example. Here, we will present an actual
+image processing example using Boost.GIL (as much as we can using only
+Boost libraries).
+Our final network will look like this:
[pre
-
-0.213436
--0.49558
-1.57538
--1.0592
-1.83927
-1.88577
-0.604675
-...
-
-]
-
-...not quite image processing, but you get the (dataflow) point :-)
-
-[heading Advantages]
-
-There are already many programming paradigms supported by C++ (either directly or through
-additional libraries), so let's examine what the advantages of the the dataflow paradigm might be.
-
-First of all, [*dataflow programming is not exclusive of other paradigms], so adopting the dataflow paradigm
-does not hinder the use of other techniques. In fact, in C++ it can't - since the components
-themselves need to be implemented somehow, and we can't recursively define them
-forever as finer and finer dataflow diagrams, the dataflow paradigm relies on other
-programming techniques to do the underlying work. Also, dataflow does not need
-be used for the entire application implementation. You can always use it
-for only those parts of the application it is appropriate for, and
-"extend your fingers" from other parts of the program in order
-to insert data into the dataflow, catch it on the other end, probe and adjust the components, etc.
-You can think of it as working with electronic components and changing the connections, turning knobs,
-flipping switches, or hanging over a circuit board and tinkering with it using, say, a multimeter and a
-5V lead (just do it with care).
-
-Second, [*dataflow promotes some good programming practices]. When developing processing components,
-we have only the incoming data to deal with - with no requirements on where it is coming from. Hence,
-the developed components tend to be quite versatile and reusable. In the above example, the image
-processing component can be used with any image data generator - there is nothing inside the component
-that says "get the image from the camera", or "get the image from this type of data source (where the
-type is either a base class or a concept)". It just does it's thing, no matter where the data is coming
-from.
-
-Third, when used in the right context, [*dataflow programming makes development and maintenance
-very intuitive]. In the image processing example, say you don't want to process the image any more. You can
-just connect the camera signal directly to the screen display and cut out
-the image processing component. Someone gives you a new video signal generator component you'd like to use as input
-instead of the camera? Just plug it in. Literally.
-
-Fourth, [*dataflow-oriented programs can be divided between threads, processors, or computers more easily],
-because the data dependencies are much more visible. In the image processing example, say you have
-the display on a different computer. You can just pass the connection to it through a network socket.
-With the data flow clearly specified, it is much easier to distribute the work either manually or
-even automatically (although the Dataflow library at the moment offers no such automatic functionality).
-
-Finally, [*we are not to far from the advantages of a [@http://en.wikipedia.org/wiki/Visual_programming_language
-visual programming language]], since the components and the connections have a natural graphical representation.
-With a visaul development environment, programming becomes as easy as connecting components with connections
-(again, the Dataflow library provides no visual programming functionality).
-
-[heading Go with the flow?]
-
-If you are interested in exploring the dataflow concept further using
-the Dataflow library, see
-
-* [how_to_use How to use this library and the documentation].
-
-[endsect][/dataflow]
-
-[section:how_to_use How to use this library and the documentation]
-
-The Dataflow library currently has two useful parts:
-
-* A layer providing generic dataflow support, adaptable to various dataflow
- mechanisms.
-* The [DataflowSignals] layer, with a number of implemented components that
- facilitate implementation of dataflow networks using [BoostSignals] as
- a data transport mechanism.
-
-There is also a (currently very experimental) [DataflowPhoenix] layer,
-which uses object pointers with support for
-[BoostPhoenix] actors specifying how the data is processed.
-
-[heading Generic dataflow layer]
-
-There are generic properties of dataflow programs which do not depend on the
-data transport mechanism,
-and can be exploited to develop mechanism-independent dataflow code.
-The generic dataflow layer captures some of these properties, and
-has been sucessfully adapted to three
-different data transport mechanisms ([BoostSignals], pointers in conjunction
-with [BoostPhoenix2], and [VTK] pipelines).
-
-Currently, the most useful functionality gained by developing a Dataflow
-support layer is the ability to connect components in a clean, readable
-manner. As more generic code is developed on top of
-the generic dataflow layer, providing a Dataflow support layer for your
-favorite data transport mechanism will be more beneficial.
-
-See the [link dataflow.future future directions] of the Dataflow library
-for an idea of what might become available in the future for data transport
-mechanisms with Dataflow library support.
-
-* If you would like to implement Dataflow support for the data transport
-mechanism you are working with, see the
-[link dataflow.introduction.examples.new_layer example] showing
-how the [VTK] support layer was developed.
-* If you are interested in developing generic code on top of the dataflow
-layer, see the [concepts] documentation.
-
-[heading Dataflow.Signals layer]
-
-This part of the Dataflow library provides components
-and connection-making capabilty which facilitates large-scale use of
-Boost.Signals as a mechanism to transfer data between processing components.
-
-For examples of how the [DataflowSignals] layer can be used, see:
-
-* The example on developing a
- [link dataflow.introduction.examples.distributed distributed dataflow application].
-* The [DataflowSignals] documentation.
-
-[/[heading When to use]
-
-While the [link dataflow.introduction.dataflow dataflow] section hopefully
-convinced you that there are circumstances in which a dataflow approach is
-useful, please keep in mind that there are many circumstances in which this
-is not the case.
-
-First, a dataflow approach really only makes sense when the underlying task is
-really about the flow of data through the components that process it.
-If you can't sketch a concise data flow diagram which truly represents
-the application, the dataflow approach might not be the best option.
-For example, if you are implementing a complicated algorithm which is really
-about the sequence of instructions that need to be executed on the data
-(rather than the data going through well-defined and self-contained
-processing components), you probably should't use the Dataflow library.
-If you are working on an audio or video processing application,
-maybe you should.
-
-Second, the data transport mechanism you choose should reflect the needs of
-the applications closely. Most of the functionality that the library supports
-at this moment is regarding run-time configurable connections. If you don't
-need that functionality, you might be wasting resources ([DataflowPhoenix]
-offers some functionality related to compile-time connectability in its
-iterator_relative connections, but that is yet to trickle out into the library
-as a whole).
-
-When using signals as the data transport mechanism, remember that every signal
-sent results in a function call, and if the processing
-components are so minute that the cost of the function
-calls overtakes the cost of the processing,
-using [DataflowSignals] will cause a significant performance hit. A similar
-situation occurs with [DataflowPhoenix], where each consumer must be invoked.
-
-To sum up, consider using the Dataflow library when:
-
-* The application can be modeled well through the flow of data; and
-* The cost of the processing shadows the cost of the function calls, and any
- unnecessary overhead caused by any connections that need to be stored.
-]
-
-
-[/[heading Dataflow library organization]
-
-The design of the Dataflow library looks like this:
-
-[xinclude dataflow_table.xml]
-
-The layers are a bottom-up hierarchy, with dependencies
-only on layers underneath.
-The /support/ layer provides the necessary generic traits and functions
-required for generic code to work with mechanism-specific
-components. Each type of mechanism or component must specialize the elements
-of the support layer to work with the mechanism\/component.
-
-Directly based on the support layer, we have functions like /connect/ and
-/invoke/, which can be used to manipulate generic and mechanism-specific
-components that the library supports. /Operators/ are based on /connect/.
-
-
-The library also offers a few generic components, which can be used
-to group other components together: [producer_group], [consumer_group],
-and [consumer_map].
-
-The rest of the library is in the mechanism-specific modules [DataflowSignals]
-and [DataflowPhoenix], each of which provide their own support layer, on
-top of which their components are implemented.
-
-As long as the support layer is implemented
-for the mechanism/component, the component should
-work seamlesly with the rest of the dataflow library.
-Essentially, the support layer is a very minimal layer implementing a generic
-and extensible intrusive directed graph framework.
-
-[heading Namespace use]
-
-Since the Dataflow library provides both a generic layer, as well as
-mechanism-specific implementations, its elements are scattered over multiple
-namespaces.
-
-The fundamental user-oriented generic elements, such as `is_producer`,
-`producer_category_of` etc., are located in the `boost::dataflow` namespace.
-Function objects which must be specialized for different data transport
-mechanisms, such as `connect_impl`, are in the `boost::dataflow::extension`
-namespace. The connection operators are in `boost::dataflow::operators`.
-
-On the other hand, individual data transport mechanism implementations
-are located in the namespace of the data transport mechanism. For example,
-all of the [DataflowSignals] components are in the `boost::signals` namespace,
-and all of the [DataflowPhoenix] components are in the `boost::phoenix`
-namespace. Furthermore, free functions such as `connect` and `invoke` are
-imported into the mechanism's namespace, so that they can be used via ADL.
-
-All of the examples shown in this documentation are assuming the use of
-
- using namespace boost;
-
-[note Since there are multiple namespaces used, the documentation will
-explicitly state the namespace of documented elements wherever it is
-convenient.]
+ .
+ ,---------.
+ | control | -----------------------+
+ \`---------' |
+ | |
+ v v
+ ,-------. ,-----------. ,-------.
+ | timer | --> | generator | -+--------------> 0 | ,---------.
+ \`-------' \`-----------' | | mux | -> | display |
+ | ,--------. | | \`---------'
+ +->| filter |--> 1 |
+ \`--------' \`-------'
+
]
-[endsect][/how_to_use]
-
-[section Examples]
-[section:new_layer Implementing support for a new mechanism (VTK)]
-
-This example shows how to implement support for a particular mechanism.
-Our victim is [VTK], a 3D visualization toolkit, which uses a data pipeline
-to move data from a source to the display (with possible transformations,
-scene construction etc. on the way). For example, here is an excerpt from
-a VTK tutorial that sets up a whole source->render window pipeline:
-
-```
- // allocate components
- vtkConeSource *cone = vtkConeSource::New();
- vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
- vtkActor *coneActor = vtkActor::New();
- vtkRenderer *ren1= vtkRenderer::New();
- vtkRenderWindow *renWin = vtkRenderWindow::New();
-
- // make the connections
- coneMapper->SetInputConnection( cone->GetOutputPort() );
- coneActor->SetMapper( coneMapper );
- ren1->AddActor( coneActor );
- renWin->AddRenderer( ren1 );
-```
-
-Our goal will be to simplify the connection-making code by providing
-Dataflow support for VTK. With that in place, we will be able to use the
-following connection code:
-
-```
- // make the connections
- connect(cone, coneMapper);
- connect(coneMapper, coneActor);
- connect(coneActor, ren1);
- connect(ren1, renWin);
-```
-
-or even more concisely and clearly,
-
-```
- // make the connections
- // C++ rules prevent us from removing all of the pointer dereferencing here
- *cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= *renWin;
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.mechanism
- Setting up the Mechanism]
-
-[section:mechanism Setting up the Mechanism]
-
-The first thing we'll do is create a tag for the VTK [MechanismConcept], in
-namespace `boost::dataflow::vtk`. Since there are currently no requirements
-for a [MechanismConcept], this is as simple as declaring a new type to be used
-as the mechanism tag:
-
-[vtk_mechanism]
-
-We will now use this tag in reference to the [VTK] dataflow mechanism.
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.producerconsumer
- Setting up a ProducerPort and ConsumerPort]
-[endsect][/mechanism]
-
-[section:producerconsumer Setting up a ProducerPort and ConsumerPort]
-
-Now that we have the mechanism, let's cover the basic data pipeline,
-which is implemented using the
-[vtkAlgorithm] class. This class provides input and output ports. Output ports
-are accessible via `GetOuptutPort` member functions, which return a proxy
-object ([vtkAlgorithmOutput] `*`) for an actual output port.
-
-In Dataflow concepts, [vtkAlgorithmOutput] can be made a [ProducerPortConcept]
-- it corresponds to a single data output point. We support it as such by
-defining a [PortTraitsConcept] type, and associating it with
-[vtkAlgorithmOutput].
-
-[vtk_algorithm_output_producer]
-
-Now that we have a [ProducerPortConcept], we need a [ConsumerPortConcept].
-[vtkAlgorithm] can accept incoming connections using the `AddInputConnection`
-and `SetInputConnection` member functions. The code below provides support
-for [vtkAlgorithm] accepting connections on its default input port:
-
-[vtk_algorithm_consumer]
-
-[heading Next]
+The role of the `timer` is to drive the network at a set frame rate.
+The `generator` will produce an image each time it receives a signal
+from the `timer`.
+The `mux` will receive two signals - one directly from the `generator` and one
+from the `filter` (which will add some noise to the generated image).
+The output of the `mux` will go to the `display`.
-[link dataflow.introduction.examples.new_layer.connectable
- Making things Connectable]
+To control the network, we will also implement a `control` component, which
+will in this case control the `generator` (setting the greyscale value of
+the generated image), and the `mux` (choosing either the filtered or the
+unfiltered image to go to the display).
-[endsect][/producerconsumer]
+Before we begin, here is some preliminary code:
-[section:connectable Making things Connectable]
+[gil_example_preliminary]
-With the pair of [ProducerPortConcept] and [ConsumerPortConcept] registered, we
-can make them [ConnectableConcept] and/or [OnlyConnectableConcept].
-All we need to do is specialize the implementation for the appropriate
-[PortTraits]:
+Our first task will be to implement an image generator. For simplicity,
+our image generator will generate a grayscale image of a specified shade:
-[vtk_connect_impl_algorithm]
+[gil_example_image_generator]
-Connections are done through the `boost::dataflow::binary_operation` function
-with either `operation::connect` or `operation::connect_only` operation tag,
-and the specified mechanism. To make connecting
-easier, we'll add forwarding connect and connect_only
-functions in the global namespace (where vtk classes live) specific
-to the vtk mechanism using the template include files for this purpose:
+Next, let's implement a filter which adds noise to the image:
-[vtk_specialize_connect]
+[gil_example_noise_adder]
-[heading What we can do with what we have so far]
+And then an image display component. In the absence of a GUI library, we will
+approximate the image display using ASCII characters.
-```
- // connect *cone to *coneMapper
- connect(*cone->GetOutputPort(), *coneMapper);
- // make *cone the only thing connected to *coneMapper
- connect_only(*cone->GetOutputPort(), *coneMapper);
-```
+[gil_example_image_display]
-[heading Next]
-[link dataflow.introduction.examples.new_layer.proxyproducer
- Setting up a ProxyProducer]
+To add some interactivity to the network, we will also implement a simple
+controller. The controller will respond to characters on `cin`, and based
+on the input output two control signals (a greyscale value for the
+`image_generator`, and an input selector signal for the multiplexer).
-[endsect][/connectable]
+[gil_example_controller]
-[section:proxyproducer Setting up a ProxyPort]
+Finally, we put together the network:
-In the VTK example above, both `vtkConeSource` and `vtkPolyDataMapper`
-inherit [vtkAlgorithm].
-With the [vtkAlgorithmOutput] [ProducerPortConcept] and
-[vtkAlgorithm] [ConsumerPortConcept] we've set up,
-we can do things like `connect(cone->GetOutputPort(), *coneMapper);`.
-However, we would like to do `connect(*cone, *coneMapper)`.
+[gil_example_main]
-To do that,
-we need to make [vtkAlgorithm] a [ProducerPortConcept]. Since [vtkAlgorithm]
-forms its output connections using [vtkAlgorithmOutput] objects
-returned through the `GetOutputPort` member functions, and we've already
-configured [vtkAlgorithmOutput] as a [ProducerPortConcept], we can make use
-of the [ProxyPortConcept] concept provided by the dataflow library.
-In effect, we will make [vtkAlgorithm] delegate it's [ProducerPortConcept]
-functionality to [vtkAlgorithmOutput]:
-
-[vtk_algorithm_proxy_producer]
-
-Now, [vtkAlgorithm] is a [ProducerPortConcept].
-
-[heading What we can do with what we have so far]
-
-```
- connect(*cone, *coneMapper)
-```
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.filter
- Setting up a filter (ProducerPort+ConsumerPort)]
-
-[endsect][/proxyproducer]
-
-[section:filter Setting up a Filter (Producer+Consumer)]
-
-In a VTK pipeline, a [vtkActor] consumes data from a [vtkMapper], and produces
-data for a [vtkRenderer]. In this case, we can provide Dataflow support
-for a [vtkActor] as both a [ProducerPortConcept] and a [ConsumerPortConcept]:
-
-[vtk_actor_filter]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.producermap
- Setting up a KeyedPort]
-
-[endsect][/filter]
-
-[section:producermap Setting up a KeyedPort]
-
-Sometimes, components can produce (or consume) multiple types of data.
-For example, [vtkMapper] objects can produce data for [vtkActor] objects,
-or (since [vtkMapper] inherits [vtkAlgorithm]) for other [vtkAlgorithm]
-objects. Correspondingly, connecting a [vtkMapper] to a [vtkActor] is not
-the same as connecting a [vtkMapper] to another [vtkAlgorithm].
-
-To accomodate such situations, the Dataflow library provides
-[KeyedPortConcept]s, which are similar to [ProxyPortConcept]s but
-the [PortConcept] they delegate to is keyed on the
-[PortConcept] they are being connected to.
-
-[vtk_mapper_producer]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.remaining
- Setting up the remaining components (more of the same)]
-
-[endsect][/producermap]
-
-[section:remaining Setting up the remaining components (more of the same)]
-
-[vtk_setup_rest]
-
-[heading Next]
-[link dataflow.introduction.examples.new_layer.pointers
- Supporting pointers]
-
-[endsect][/remaining]
-
-[section:pointers Supporting pointers]
-
-All of the concepts we adapted so far have been adapted for class types such
-as [vtkAlgorithm] and [vtkAlgorithmOutput]. But [VTK] seems to exclusively
-use pointers to class types rather than class types themselves. So, with what
-we have done so far, we can do `connect(*cone, *coneMapper)` but not
-`connect(cone, coneMapper)`. To provide support for pointers, we
-simply make them adhere to the [ProxyPortConcept] concept, and delegate the
-functionality to the object they point to.
-
-[vtk_support_pointer]
-
-[endsect][/pointers]
-
-
-
-[endsect][/new_layer]
-
-[section:distributed Implementing distributed dataflow applications using
- Dataflow.Signals and Boost.Asio]
-
-This example shows how you can take advantage of dataflow programming
-to create distributed applications. It works as long as the data
-passed in the signal is serializable using [BoostSerialization].
-
-[DataflowSignals] provides two components
-which can be used to create a producer-consumer connection between two
-computers: [socket_sender] and [socket_receiver]. As long as we have
-a network socket set up between two computers, we can do the following to
-set up a connection between a [SignalProducerConcept] on one computer with a
-[SignalConsumerConcept] on another:
-
-* On the [SignalProducerConcept]'s computer, construct a [socket_sender] of
-the appropriate `Signature` with the given socket.
-[connect] the [SignalProducerConcept] to the [socket_sender].
-* On the [SignalConsumerConcept]'s computer, construct a [socket_receiver] of
-the appropriate `Signature` with the given socket.
-[connect] the [socket_receiver] to the [SignalConsumerConcept].
-
-That's it. Now, every signal sent out of the [SignalProducerConcept] should
-be received by the [SignalConsumerConcept].
-
-The following is a modification of the example from the
-[link dataflow.introduction.dataflow motivation section] to a dataflow
-network that straddles a network socket:
-
-[simple_distributed_example]
-
-A sample run produces:
+Here is some sample output (with input characters marked):
[pre
-0.213436
--0.49558
-1.57538
--1.0592
-1.83927
-1.88577
-...
-]
-
-[endsect][/distributed]
-
-[endsect][/examples]
-
-[section:download Downloading, building and linking]
-
-[heading Downloading]
-I am currently preparing this library for submission for a Boost review. The
-latest version is located in the
-[@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/signals Boost sandbox].
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+
+. <-- input (increase grayscale value)
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+;;;;;;;;;;
+
+. <-- input (increase grayscale value)
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+
+. <-- input (increase grayscale value)
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+
+. <-- input (increase grayscale value)
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+
+, <-- input (decrease grayscale value)
+
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+
+1 <-- input (switch multiplexer to output of noise adder)
+\*\*\*\*#\*\*#\*#
+###\*\*\*\*\*\*\*
+\*\*\*\*\*\*\*\*\*\*
+#\*\*######\*
+\*#\*#\*\*\*\*\*\*
+\*\*#\*#\*####
+\*\*##\*\*\*\*#\*
+\*\*\*#\*\*\*\*\*\*
+\*###\*\*\*##\*
+\*\*\*#\*\*\*\*\*#
+
+\*\*\*#\*\*\*\*\*#
+#\*\*#\*#\*#\*\*
+#\*\*##\*\*#\*\*
+\*#\*\*\*\*\*#\*#
+#;#\*\*#\*\*\*#
+\*\*\*\*###\*#\*
+\*\*#\*\*\*####
+\*#\*\*\*\*\*\*\*#
+\*\*######\*\*
+\*\*##\*\*\*##\*
+
+#\*\*\*\*\*\*\*\*\*
+\*\*#\*#\*\*\*#\*
+\*\*#\*\*\*\*\*#\*
+\*#\*\*#\*\*\*#\*
+\*\*\*\*\*#\*\*##
+\*\*\*\*\*\*#\*#\*
+\*\*\*\*#\*\*\*#\*
+\*\*#\*\*\*\*\*\*#
+\*\*\*\*#\*\*\*\*\*
+#\*\*\*######
+
+. <-- input (increase grayscale value)
+\*#########
+######\*###
+#######\*$#
+##########
+####$#####
+#####\*####
+#\*##\*#####
+##########
+##\*######\*
+########$#
+
+0 <-- input (switch mutiplexer back to the generated image)
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+##########
+##########
-Version 0.8.0 -
- \[[@http://www.boost-consulting.com/vault/index.php?direction=&order=&directory=Dataflow& available in the Boost vault]\]
-
-* post-GSoC version
-* generic dataflow support layer with tests and examples
-* Dataflow.Signals layer (fusion-based implementation) with tests and examples
-* VTK example
-* quickbook docs
-
-[/Proposal for Boost / Google SoC version \[[@signal_network.zip download]\]
-
-* finished the signals::socket_sender and signals::socket_receiver components
-
-Draft proposal for Boost / Google SoC version
-
-* changed the file and namespace structure
-* implemented a file-iteration based mechanism for arity-dependent classes
-* changed the operators used
-* signal_link is now signals::filter and does not need to know it's descendant's type
-* implemented signals::junction, signals::selector, signals::storage, signals::timed_generator,
- signals::mutex, signals::chain, signals::function classes
-
-Original request for interest version available as attachment to
-[@http://lists.boost.org/Archives/boost/2007/02/116869.php]
]
-[heading Building]
-
-The library comes with Boost.Build Jamfiles for all examples, tests, and docs.
-As long as your BOOST_ROOT environment variable is set, you should be able
-to build each one of those by going to the appropriate directory and
-running bjam.
-
-The library itself is header only, and requires no linking. However, parts
-of it depend on boost libraries which do need to be built and linked (see
-the linking information below).
-
-[heading Linking]
-
-The generic Dataflow support layer is header-only, and relies only on other
-Boost header-only libraries (MPL, enable_if, and small parts of fusion).
-
-The [DataflowSignals] layer is dependent on the [BoostSignals] library,
-which must be built and linked. A few of the components ([socket_sender]
-and [socket_receiver]) are also dependent on [BoostAsio], which depends on
-the System library which must also be built and linked. A few other components
-([mutex] and [condition]) are dependent on [BoostThread], which has to be
-linked as well.
-
-[endsect][/download]
-
-[endsect][/introduction]
+[endsect]
Copied: sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/vtk_example.qbk (from r41018, /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk)
==============================================================================
--- /sandbox/SOC/2007/signals/libs/dataflow/doc/introduction.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/introduction/vtk_example.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -1,341 +1,3 @@
-[section:introduction Introduction]
-
-Dataflow is a generic library for [WikiDataflow] programming using various data
-transport mechanisms. It also has layers of support for
-two data transport mechanisms - one is based on
-[BoostSignals], and the other (experimental and currently broken) is based
-connections made through
-simple object pointers, with support for using [BoostPhoenix2]
-actors for data processing.
-
-The two data transport mechanisms are implemented in the [DataflowSignals]
-and [DataflowPhoenix] layers. The idea behind providing a generic dataflow
-library is that other data transport mechanisms can be easily adapted for
-use with the library.
-
-[warning Dataflow is not a part of the Boost libraries. It is being developed
-as a part of the Google Summer of Code program. The original proposal (for
-the Signal Network library, which became the Dataflow library)
-as well as some status updates can be found on the
-[@http://svn.boost.org/trac/boost/wiki/soc/2007/SignalNetwork GSoC page].]
-
-* If you would like some more information about why one would want to connect
- objects into a dataflow network, read about
- [link dataflow.introduction.dataflow Dataflow programming in C++].
-* If you'd like to try out the library
- * keep in mind that the interface is subject to change
- * Read [how_to_use how to use this library and the documentation].
-
-
-[section:dataflow Dataflow programming in C++ - motivation and advantages]
-
-The [WikiDataflow] programming paradigm is based on interconnected
-/components/ which process passing /data/. Basically, data is treated
-as something that originates from a source, flows through a number of
-processing components that manipulate it (e.g., by changing it,
-duplicating, etc.), and arrives at some final destination. As such,
-the dataflow paradigm is most suitable when developing applications that
-are themselves focused on the "flow" of data.
-
-Perhaps the most readily available examples of a
-dataflow-oriented applications come from the realm of real-time
-[@http://en.wikipedia.org/wiki/Signal_processing signal processing],
-e.g. a video signal processor which perhaps starts with a video input,
-modifies it through a number of processing components (video filters),
-and finally outputs it to a video display. Another example is event
-processing.
-
-[heading A motivating example]
-
-Let's take a simple real-time camera-input-displayed-on-the-screen application.
-Suppose there are three parts to the application - getting each image frame
-from the camera, processing the image in some way,
-and displaying it on the screen. To see how we might arrive at
-a dataflow-oriented implementation of this application,
-let's first begin with an imperative approach. Such an implementation might
-be structured as follows:
-
-[$dataflow1.png]
-
-Basically, the main program loop is a series of instructions which does
-this particular job. To take this a step further in the dataflow direction,
-we note that video input libraries often provide callback
-functionality which will deliver a video stream as a sequence of
-image frames given at the appropriate frame rate.
-With this in mind, we do the following:
-
-# implement a function which takes an image as input.
- # the function first invokes the image processing library function that
- modifies the image as appropriate
- # the function then invokes the GUI library function that displays the image
-# register the function as a callback with the camera library
-# the main program loop can relax and have some coffee.
-
-The situation now looks something like this:
-
-[$dataflow2.png]
-
-So now, the image library is acting as a data/signal producer - it
-generates images at a certain frame rate. And the function we
-implemented seems to be a signal consumer which can take an image,
-process it, and display it on the screen.
-
-This now employs the basic elements of the dataflow paradigm, but we could
-take it even further. Instead of just having two components, one image
-signal generator and one signal consumer, how about this:
-
-# implement a component which accepts an input image signal,
- modifies the image as appropriate, and then outputs
- a signal with the modified image
-# implement a component which receives an imput image signal and displays
- it on the screen
-# connect the camera library input stream to the first component
-# connect the first component to the second component
-# the main program loop can relax and have some tea, or even take a nap.
-
-The big picture now looks like the following:
-
-[$dataflow3.png]
-
-To give you a sense of how you would do something like this using the Dataflow
-library, we will present a slightly simplified example using [DataflowSignals].
-Instead of processing images, we will just process numbers - but the dataflow
-parts of the code are pretty much the same.
-
-We will first define a few components to use for our network:
-
-[simple_example_components]
-
-And then connect them in a dataflow network:
-
-[simple_example]
-
-A sample run produces:
-
-[pre
-
-0.213436
--0.49558
-1.57538
--1.0592
-1.83927
-1.88577
-0.604675
-...
-
-]
-
-...not quite image processing, but you get the (dataflow) point :-)
-
-[heading Advantages]
-
-There are already many programming paradigms supported by C++ (either directly or through
-additional libraries), so let's examine what the advantages of the the dataflow paradigm might be.
-
-First of all, [*dataflow programming is not exclusive of other paradigms], so adopting the dataflow paradigm
-does not hinder the use of other techniques. In fact, in C++ it can't - since the components
-themselves need to be implemented somehow, and we can't recursively define them
-forever as finer and finer dataflow diagrams, the dataflow paradigm relies on other
-programming techniques to do the underlying work. Also, dataflow does not need
-be used for the entire application implementation. You can always use it
-for only those parts of the application it is appropriate for, and
-"extend your fingers" from other parts of the program in order
-to insert data into the dataflow, catch it on the other end, probe and adjust the components, etc.
-You can think of it as working with electronic components and changing the connections, turning knobs,
-flipping switches, or hanging over a circuit board and tinkering with it using, say, a multimeter and a
-5V lead (just do it with care).
-
-Second, [*dataflow promotes some good programming practices]. When developing processing components,
-we have only the incoming data to deal with - with no requirements on where it is coming from. Hence,
-the developed components tend to be quite versatile and reusable. In the above example, the image
-processing component can be used with any image data generator - there is nothing inside the component
-that says "get the image from the camera", or "get the image from this type of data source (where the
-type is either a base class or a concept)". It just does it's thing, no matter where the data is coming
-from.
-
-Third, when used in the right context, [*dataflow programming makes development and maintenance
-very intuitive]. In the image processing example, say you don't want to process the image any more. You can
-just connect the camera signal directly to the screen display and cut out
-the image processing component. Someone gives you a new video signal generator component you'd like to use as input
-instead of the camera? Just plug it in. Literally.
-
-Fourth, [*dataflow-oriented programs can be divided between threads, processors, or computers more easily],
-because the data dependencies are much more visible. In the image processing example, say you have
-the display on a different computer. You can just pass the connection to it through a network socket.
-With the data flow clearly specified, it is much easier to distribute the work either manually or
-even automatically (although the Dataflow library at the moment offers no such automatic functionality).
-
-Finally, [*we are not to far from the advantages of a [@http://en.wikipedia.org/wiki/Visual_programming_language
-visual programming language]], since the components and the connections have a natural graphical representation.
-With a visaul development environment, programming becomes as easy as connecting components with connections
-(again, the Dataflow library provides no visual programming functionality).
-
-[heading Go with the flow?]
-
-If you are interested in exploring the dataflow concept further using
-the Dataflow library, see
-
-* [how_to_use How to use this library and the documentation].
-
-[endsect][/dataflow]
-
-[section:how_to_use How to use this library and the documentation]
-
-The Dataflow library currently has two useful parts:
-
-* A layer providing generic dataflow support, adaptable to various dataflow
- mechanisms.
-* The [DataflowSignals] layer, with a number of implemented components that
- facilitate implementation of dataflow networks using [BoostSignals] as
- a data transport mechanism.
-
-There is also a (currently very experimental) [DataflowPhoenix] layer,
-which uses object pointers with support for
-[BoostPhoenix] actors specifying how the data is processed.
-
-[heading Generic dataflow layer]
-
-There are generic properties of dataflow programs which do not depend on the
-data transport mechanism,
-and can be exploited to develop mechanism-independent dataflow code.
-The generic dataflow layer captures some of these properties, and
-has been sucessfully adapted to three
-different data transport mechanisms ([BoostSignals], pointers in conjunction
-with [BoostPhoenix2], and [VTK] pipelines).
-
-Currently, the most useful functionality gained by developing a Dataflow
-support layer is the ability to connect components in a clean, readable
-manner. As more generic code is developed on top of
-the generic dataflow layer, providing a Dataflow support layer for your
-favorite data transport mechanism will be more beneficial.
-
-See the [link dataflow.future future directions] of the Dataflow library
-for an idea of what might become available in the future for data transport
-mechanisms with Dataflow library support.
-
-* If you would like to implement Dataflow support for the data transport
-mechanism you are working with, see the
-[link dataflow.introduction.examples.new_layer example] showing
-how the [VTK] support layer was developed.
-* If you are interested in developing generic code on top of the dataflow
-layer, see the [concepts] documentation.
-
-[heading Dataflow.Signals layer]
-
-This part of the Dataflow library provides components
-and connection-making capabilty which facilitates large-scale use of
-Boost.Signals as a mechanism to transfer data between processing components.
-
-For examples of how the [DataflowSignals] layer can be used, see:
-
-* The example on developing a
- [link dataflow.introduction.examples.distributed distributed dataflow application].
-* The [DataflowSignals] documentation.
-
-[/[heading When to use]
-
-While the [link dataflow.introduction.dataflow dataflow] section hopefully
-convinced you that there are circumstances in which a dataflow approach is
-useful, please keep in mind that there are many circumstances in which this
-is not the case.
-
-First, a dataflow approach really only makes sense when the underlying task is
-really about the flow of data through the components that process it.
-If you can't sketch a concise data flow diagram which truly represents
-the application, the dataflow approach might not be the best option.
-For example, if you are implementing a complicated algorithm which is really
-about the sequence of instructions that need to be executed on the data
-(rather than the data going through well-defined and self-contained
-processing components), you probably should't use the Dataflow library.
-If you are working on an audio or video processing application,
-maybe you should.
-
-Second, the data transport mechanism you choose should reflect the needs of
-the applications closely. Most of the functionality that the library supports
-at this moment is regarding run-time configurable connections. If you don't
-need that functionality, you might be wasting resources ([DataflowPhoenix]
-offers some functionality related to compile-time connectability in its
-iterator_relative connections, but that is yet to trickle out into the library
-as a whole).
-
-When using signals as the data transport mechanism, remember that every signal
-sent results in a function call, and if the processing
-components are so minute that the cost of the function
-calls overtakes the cost of the processing,
-using [DataflowSignals] will cause a significant performance hit. A similar
-situation occurs with [DataflowPhoenix], where each consumer must be invoked.
-
-To sum up, consider using the Dataflow library when:
-
-* The application can be modeled well through the flow of data; and
-* The cost of the processing shadows the cost of the function calls, and any
- unnecessary overhead caused by any connections that need to be stored.
-]
-
-
-[/[heading Dataflow library organization]
-
-The design of the Dataflow library looks like this:
-
-[xinclude dataflow_table.xml]
-
-The layers are a bottom-up hierarchy, with dependencies
-only on layers underneath.
-The /support/ layer provides the necessary generic traits and functions
-required for generic code to work with mechanism-specific
-components. Each type of mechanism or component must specialize the elements
-of the support layer to work with the mechanism\/component.
-
-Directly based on the support layer, we have functions like /connect/ and
-/invoke/, which can be used to manipulate generic and mechanism-specific
-components that the library supports. /Operators/ are based on /connect/.
-
-
-The library also offers a few generic components, which can be used
-to group other components together: [producer_group], [consumer_group],
-and [consumer_map].
-
-The rest of the library is in the mechanism-specific modules [DataflowSignals]
-and [DataflowPhoenix], each of which provide their own support layer, on
-top of which their components are implemented.
-
-As long as the support layer is implemented
-for the mechanism/component, the component should
-work seamlesly with the rest of the dataflow library.
-Essentially, the support layer is a very minimal layer implementing a generic
-and extensible intrusive directed graph framework.
-
-[heading Namespace use]
-
-Since the Dataflow library provides both a generic layer, as well as
-mechanism-specific implementations, its elements are scattered over multiple
-namespaces.
-
-The fundamental user-oriented generic elements, such as `is_producer`,
-`producer_category_of` etc., are located in the `boost::dataflow` namespace.
-Function objects which must be specialized for different data transport
-mechanisms, such as `connect_impl`, are in the `boost::dataflow::extension`
-namespace. The connection operators are in `boost::dataflow::operators`.
-
-On the other hand, individual data transport mechanism implementations
-are located in the namespace of the data transport mechanism. For example,
-all of the [DataflowSignals] components are in the `boost::signals` namespace,
-and all of the [DataflowPhoenix] components are in the `boost::phoenix`
-namespace. Furthermore, free functions such as `connect` and `invoke` are
-imported into the mechanism's namespace, so that they can be used via ADL.
-
-All of the examples shown in this documentation are assuming the use of
-
- using namespace boost;
-
-[note Since there are multiple namespaces used, the documentation will
-explicitly state the namespace of documented elements wherever it is
-convenient.]
-]
-
-[endsect][/how_to_use]
-
-[section Examples]
[section:new_layer Implementing support for a new mechanism (VTK)]
This example shows how to implement support for a particular mechanism.
@@ -379,6 +41,19 @@
*cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= *renWin;
```
+[note Going through the following pages, you might think that implementing a VTK
+support layer is a whole lot of effort for very little benefit. Please keep the
+following in mind:
+
+* The support layer needs to be implemented only once (per mechanism). Since
+ this example takes care of [VTK], to get the
+ benefits of the Dataflow library (which are admitedly few at the moment)
+ all you need to do is include the provided header.
+
+* Once more things are implemented on top of the generic Dataflow layer, having
+ Dataflow library support will be more beneficial.
+]
+
[heading Next]
[link dataflow.introduction.examples.new_layer.mechanism
Setting up the Mechanism]
@@ -410,10 +85,13 @@
In Dataflow concepts, [vtkAlgorithmOutput] can be made a [ProducerPortConcept]
- it corresponds to a single data output point. We support it as such by
defining a [PortTraitsConcept] type, and associating it with
-[vtkAlgorithmOutput].
+[vtkAlgorithmOutput]:
[vtk_algorithm_output_producer]
+[note More details about registering [PortTraitsConcept] for a [PortConcept]
+can be found on the [PortConcept] documentation page.]
+
Now that we have a [ProducerPortConcept], we need a [ConsumerPortConcept].
[vtkAlgorithm] can accept incoming connections using the `AddInputConnection`
and `SetInputConnection` member functions. The code below provides support
@@ -433,16 +111,55 @@
With the pair of [ProducerPortConcept] and [ConsumerPortConcept] registered, we
can make them [ConnectableConcept] and/or [OnlyConnectableConcept].
All we need to do is specialize the implementation for the appropriate
-[PortTraits]:
+[PortTraitsConcept]:
[vtk_connect_impl_algorithm]
Connections are done through the `boost::dataflow::binary_operation` function
with either `operation::connect` or `operation::connect_only` operation tag,
-and the specified mechanism. To make connecting
+and the specified mechanism. In the next step, we'll set up forwarding functions
+and operators that will make connections easier.
+
+[heading What we can do with what we have so far]
+
+```
+ // connect *cone to *coneMapper
+ boost::dataflow::binary_operation<
+ boost::dataflow::operation::connect,
+ boost::dataflow::vtk::mechanism>
+ (*cone->GetOutputPort(), *coneMapper);
+
+ // make *cone the only thing connected to *coneMapper
+ boost::dataflow::binary_operation<
+ boost::dataflow::operation::connect_only,
+ boost::dataflow::vtk::mechanism>
+ (*cone->GetOutputPort(), *coneMapper);
+
+```
+
+[heading Next]
+[link dataflow.introduction.examples.new_layer.forwarding
+ Defining forwarding functions and operators]
+
+[endsect][/connectable]
+
+[section:forwarding Defining forwarding functions and operators]
+
+To make connecting
easier, we'll add forwarding connect and connect_only
functions in the global namespace (where vtk classes live) specific
-to the vtk mechanism using the template include files for this purpose:
+to the vtk mechanism. The Dataflow library provides inlcude file templates
+for this purpose.
+
+Including `<boost/dataflow/templates/binary_operation.hpp>` with `#define`d
+DATAFLOW_TEMPLATE_MECHANISM and DATAFLOW_TEMPLATE_BINARY_OPERATION will
+define a forwarding function DATAFLOW_TEMPLATE_BINARY_OPERATION in the
+current namespace.
+
+Including `<boost/dataflow/templates/operator.hpp>` with `#define`d
+DATAFLOW_TEMPLATE_MECHANISM, DATAFLOW_TEMPLATE_BINARY_OPERATION, and
+DATAFLOW_TEMPLATE_OPERATOR will define a forwarding operator in the current
+namespace.
[vtk_specialize_connect]
@@ -451,15 +168,21 @@
```
// connect *cone to *coneMapper
connect(*cone->GetOutputPort(), *coneMapper);
+ // or
+ *cone->GetOutputPort() >>= *coneMapper
+
// make *cone the only thing connected to *coneMapper
connect_only(*cone->GetOutputPort(), *coneMapper);
+ // or
+ *cone->GetOutputPort() ^= *coneMapper
+
```
[heading Next]
[link dataflow.introduction.examples.new_layer.proxyproducer
Setting up a ProxyProducer]
-[endsect][/connectable]
+[endsect][/forwarding]
[section:proxyproducer Setting up a ProxyPort]
@@ -552,115 +275,22 @@
[vtk_support_pointer]
-[endsect][/pointers]
-
-
-
-[endsect][/new_layer]
-
-[section:distributed Implementing distributed dataflow applications using
- Dataflow.Signals and Boost.Asio]
-
-This example shows how you can take advantage of dataflow programming
-to create distributed applications. It works as long as the data
-passed in the signal is serializable using [BoostSerialization].
-
-[DataflowSignals] provides two components
-which can be used to create a producer-consumer connection between two
-computers: [socket_sender] and [socket_receiver]. As long as we have
-a network socket set up between two computers, we can do the following to
-set up a connection between a [SignalProducerConcept] on one computer with a
-[SignalConsumerConcept] on another:
-
-* On the [SignalProducerConcept]'s computer, construct a [socket_sender] of
-the appropriate `Signature` with the given socket.
-[connect] the [SignalProducerConcept] to the [socket_sender].
-* On the [SignalConsumerConcept]'s computer, construct a [socket_receiver] of
-the appropriate `Signature` with the given socket.
-[connect] the [socket_receiver] to the [SignalConsumerConcept].
-
-That's it. Now, every signal sent out of the [SignalProducerConcept] should
-be received by the [SignalConsumerConcept].
-
-The following is a modification of the example from the
-[link dataflow.introduction.dataflow motivation section] to a dataflow
-network that straddles a network socket:
-
-[simple_distributed_example]
-
-A sample run produces:
-
-[pre
-0.213436
--0.49558
-1.57538
--1.0592
-1.83927
-1.88577
-...
-]
-
-[endsect][/distributed]
-
-[endsect][/examples]
-
-[section:download Downloading, building and linking]
-
-[heading Downloading]
-
-I am currently preparing this library for submission for a Boost review. The
-latest version is located in the
-[@http://svn.boost.org/trac/boost/browser/sandbox/SOC/2007/signals Boost sandbox].
-
-Version 0.8.0 -
- \[[@http://www.boost-consulting.com/vault/index.php?direction=&order=&directory=Dataflow& available in the Boost vault]\]
-
-* post-GSoC version
-* generic dataflow support layer with tests and examples
-* Dataflow.Signals layer (fusion-based implementation) with tests and examples
-* VTK example
-* quickbook docs
-
-[/Proposal for Boost / Google SoC version \[[@signal_network.zip download]\]
-
-* finished the signals::socket_sender and signals::socket_receiver components
-
-Draft proposal for Boost / Google SoC version
-
-* changed the file and namespace structure
-* implemented a file-iteration based mechanism for arity-dependent classes
-* changed the operators used
-* signal_link is now signals::filter and does not need to know it's descendant's type
-* implemented signals::junction, signals::selector, signals::storage, signals::timed_generator,
- signals::mutex, signals::chain, signals::function classes
-
-Original request for interest version available as attachment to
-[@http://lists.boost.org/Archives/boost/2007/02/116869.php]
-]
-
-[heading Building]
+[heading Next]
+[link dataflow.introduction.examples.new_layer.using_support_layer
+ Using the VTK support layer]
-The library comes with Boost.Build Jamfiles for all examples, tests, and docs.
-As long as your BOOST_ROOT environment variable is set, you should be able
-to build each one of those by going to the appropriate directory and
-running bjam.
+[endsect][/pointers]
-The library itself is header only, and requires no linking. However, parts
-of it depend on boost libraries which do need to be built and linked (see
-the linking information below).
+[section:using_support_layer Using the VTK support layer]
-[heading Linking]
+Now that we have developed a support layer for VTK, what do we get?
-The generic Dataflow support layer is header-only, and relies only on other
-Boost header-only libraries (MPL, enable_if, and small parts of fusion).
+Well, at the moment, one of the largest practical benefits is a small
+improvement to the connection syntax. Here is a full VTK example which
+has been modified to use the Dataflow library for making connections:
-The [DataflowSignals] layer is dependent on the [BoostSignals] library,
-which must be built and linked. A few of the components ([socket_sender]
-and [socket_receiver]) are also dependent on [BoostAsio], which depends on
-the System library which must also be built and linked. A few other components
-([mutex] and [condition]) are dependent on [BoostThread], which has to be
-linked as well.
+[vtk_example_Cone_cxx]
-[endsect][/download]
+[endsect]
-[endsect][/introduction]
+[endsect][/new_layer]
Modified: sandbox/SOC/2007/signals/libs/dataflow/doc/port_concepts.qbk
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/doc/port_concepts.qbk (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/doc/port_concepts.qbk 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -148,7 +148,7 @@
[`get_port_result_type<M,PC,P>::type`]
[
Returns the underlying port object. With regular ports,
- this is typically the same as `p`. With [ProxyPortConcept]
+ this is typically a reference to `p`. With [ProxyPortConcept]
objects, it is typically the proxied port object.
]
]
@@ -165,18 +165,66 @@
[heading Notes]
-To specify that a type `P` is a [PortConcept],
-it suffices to provide a specialization of `port_traits_of`.
-This can either be done explicitly, or intrusively by providing
-a `P::port_traits` member type specifying the
-[PortTraitsConcept]. `P::port_traits` can either be a [PortTraitsConcept]
-type, or an MPL sequence of [PortTraitsConcept] types.
+There is an intrusive as well as a non-intrusive way to register the
+[PortTraitsConcept] of a type `P`, thereby making it a [PortConcept].
-The Dataflow library provides a convenience class
+Non-intrusive registration is done by providing a specialization of
+the `port_traits_of` template (either directly, or through the provided
+macros DATAFLOW_PORT_TRAITS and DATAFLOW_PORT_TRAITS_ENABLE_IF).
+
+Intrusive registration can be done by providing
+a `P::port_traits` member type, which can be either a [PortTraitsConcept]
+type, or an MPL sequence of [PortTraitsConcept] types. Alternatively,
+the Dataflow library provides a convenience class
`port` which you can inherit instead of declaring the member type.
+The below examples illustrate the avaliable registration methods.
+
[heading Examples]
+All of the below examples use the following [MechanismConcept] and
+[PortTraitsConcept] types:
+
+[port_registration_example_prep]
+
+[heading Intrusive registration]
+
+Intrusive registration is the easiest, but assumes you can modify the
+[PortConcept]:
+
+[port_registration_example_intrusive]
+
+[heading Non-intrusive registration]
+
+Non-intrusive registration is done by specializing the `port_traits_of`
+template. Since the `port_traits_of` template is keyed by [MechanismConcept]
+and [PortCategoryConcept], this is rather verbose:
+
+[port_registration_example_non_intrusive]
+
+To make things simpler, the Dataflow library provides a macro for non-intrusive
+registration (the macro also performs a static check on the
+[PortTraitsConcept]).
+
+[port_registration_example_non_intrusive_macro]
+
+[heading Non-intrusive mass registration]
+
+The `port_traits_of` template has an Enable template parameter for use with
+`boost::enable_if`. Hence, we can register a number of types at the same time:
+
+[port_registration_example_non_intrusive_enable_if]
+
+And again, there is a convenient macro:
+
+[port_registration_example_non_intrusive_enable_if_macro]
+
+[heading Tests]
+
+With the above registrations, the following tests pass:
+
+[port_registration_check_example]
+
[endsect][/port]
[section ProxyPortTraits]
Modified: sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone.cxx
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone.cxx (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone.cxx 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -1,3 +1,5 @@
+//[ vtk_example_Cone_cxx
+
/*=========================================================================
Program: Visualization Toolkit
@@ -11,6 +13,9 @@
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
+ NOTE: This is a MODIFIED version of the original Cone.cxx distributed
+ with VTK. Modifications (c) Stjepan Rajko 2007
+
=========================================================================*/
//
// This example creates a polygonal model of a cone, and then renders it to
@@ -21,8 +26,6 @@
// First include the required header files for the VTK classes we are using.
-#include "operators.hpp"
-
#include "vtkAlgorithmOutput.h"
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
@@ -31,11 +34,11 @@
#include "vtkActor.h"
#include "vtkRenderer.h"
+// ... and include the VTK Dataflow support layer.
+#include "vtk_dataflow_support.hpp"
int main()
{
- //using boost::dataflow::connect;
- //using namespace boost::dataflow::operators;
//
// Next we create an instance of vtkConeSource and set some of its
@@ -56,8 +59,6 @@
// connect the output of the cone souece to the input of this mapper.
//
vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
- //coneMapper->SetInputConnection( cone->GetOutputPort() );
- //connect(*cone, *coneMapper);
//
// Create an actor to represent the cone. The actor orchestrates rendering
@@ -67,8 +68,6 @@
// above.
//
vtkActor *coneActor = vtkActor::New();
- //coneActor->SetMapper( coneMapper );
- //connect (*coneMapper, *coneActor);
//
// Create the Renderer and assign actors to it. A renderer is like a
@@ -77,8 +76,6 @@
// color here.
//
vtkRenderer *ren1= vtkRenderer::New();
- //connect (*coneActor, *ren1);
-// ren1->AddActor( coneActor );
ren1->SetBackground( 0.1, 0.2, 0.4 );
//
@@ -87,11 +84,17 @@
// set the size to be 300 pixels by 300.
//
vtkRenderWindow *renWin = vtkRenderWindow::New();
-// renWin->AddRenderer( ren1 );
renWin->SetSize( 300, 300 );
- *cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= renWin;
-
+ // Finally, connect everything using the VTK Dataflow support layer:
+ *cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= *renWin;
+
+ // NOTE: this replaced the following code:
+ // coneMapper->SetInput( cone->GetOutput() );
+ // coneActor->SetMapper( coneMapper );
+ // ren1->AddActor( coneActor );
+ // renWin->AddRenderer( ren1 );
+
//
// Now we loop over 360 degreeees and render the cone each time.
//
@@ -117,4 +120,4 @@
return 0;
}
-
+//]
\ No newline at end of file
Modified: sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone2.cxx
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone2.cxx (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/VTK/Cone2.cxx 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -11,6 +11,9 @@
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
+ NOTE: This is a MODIFIED version of the original Cone.cxx distributed
+ with VTK. Modifications (c) Stjepan Rajko 2007
+
=========================================================================*/
//
// This example shows how to add an observer to a C++ program. It extends
@@ -24,8 +27,6 @@
// is observed.
//
-#include "operators.hpp"
-
// first include the required header files for the vtk classes we are using
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
@@ -35,6 +36,8 @@
#include "vtkActor.h"
#include "vtkRenderer.h"
+#include "vtk_dataflow_support.hpp"
+
// Callback for the interaction
class vtkMyCallback : public vtkCommand
{
@@ -61,17 +64,13 @@
cone->SetResolution( 10 );
vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
- //coneMapper->SetInputConnection( cone->GetOutputPort() );
vtkActor *coneActor = vtkActor::New();
- //coneActor->SetMapper( coneMapper );
vtkRenderer *ren1= vtkRenderer::New();
- //ren1->AddActor( coneActor );
ren1->SetBackground( 0.1, 0.2, 0.4 );
ren1->ResetCamera();
vtkRenderWindow *renWin = vtkRenderWindow::New();
- //renWin->AddRenderer( ren1 );
renWin->SetSize( 300, 300 );
*cone >>= *coneMapper >>= *coneActor >>= *ren1 >>= *renWin;
Deleted: sandbox/SOC/2007/signals/libs/dataflow/example/VTK/operators.hpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/VTK/operators.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
+++ (empty file)
@@ -1,61 +0,0 @@
-// Copyright Stjepan Rajko 2007. 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)
-
-#ifndef BOOST_DATAFLOW_VTK_CONNECTION_OPERATORS_HPP
-#define BOOST_DATAFLOW_VTK_CONNECTION_OPERATORS_HPP
-
-#include "support.hpp"
-
-#include <boost/mpl/and.hpp>
-
-
-/// Connects two components (typically as a part of a chain of components).
-/** This operator is identical to signals::operator| (it connects the
-left component to the right component, and returns a reference to the left component),
-except it is evaluated right to left. This makes it semantics more suitable for
-connecting a chain of components.
-*/
-template<typename Input, typename Output>
-typename boost::enable_if<
- boost::mpl::and_<
- boost::dataflow::is_port<boost::dataflow::vtk::mechanism, boost::dataflow::ports::producer, Input>,
- boost::dataflow::is_port<boost::dataflow::vtk::mechanism, boost::dataflow::ports::consumer, Output>
- >,
- Input &
->::type
-operator >>= (Input &input, Output &output)
-{ connect(input, output); return input;}
-
-/// Connects two components (typically as a part of a chain of components).
-template<typename Input, typename Output>
-typename boost::enable_if<
- boost::mpl::and_<
- boost::dataflow::is_port<boost::dataflow::vtk::mechanism, boost::dataflow::ports::producer, Input>,
- boost::dataflow::is_port<boost::dataflow::vtk::mechanism, boost::dataflow::ports::consumer, Output>
- >,
- Input &
->::type
-operator ^= (Input &input, Output &output)
-{ connect_only(input, output); return input;}
-
-/// Connects two components (typically as a part of branching from a single component).
-/** This operator is identical to signals::operator>>=, (it connects the
-left component to the right component, and returns a reference to the left component)
-except it is evaluated left to right. This makes its semantics more suitable for
-branching connections.
-*/
-template<typename Input, typename Output>
-typename boost::enable_if<
- boost::mpl::and_<
- boost::dataflow::is_port<boost::dataflow::vtk::mechanism, boost::dataflow::ports::producer, Input>,
- boost::dataflow::is_port<boost::dataflow::vtk::mechanism, boost::dataflow::ports::consumer, Output>
- >,
- Input &
->::type
-operator | (Input &input, Output &output)
-{ connect(input, output); return input;}
-
-#endif // BOOST_DATAFLOW_VTK_CONNECTION_OPERATORS_HPP
-
Deleted: sandbox/SOC/2007/signals/libs/dataflow/example/VTK/support.hpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/VTK/support.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
+++ (empty file)
@@ -1,397 +0,0 @@
-// Copyright Stjepan Rajko 2007. 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)
-
-#ifndef BOOST_DATAFLOW_VTK_SUPPORT_HPP
-#define BOOST_DATAFLOW_VTK_SUPPORT_HPP
-
-#include "vtkAlgorithmOutput.h"
-#include "vtkActor.h"
-#include "vtkAlgorithm.h"
-#include "vtkRenderWindow.h"
-
-#include <boost/dataflow/support.hpp>
-#include <boost/dataflow/connection/port_map.hpp>
-
-#include <boost/assert.hpp>
-#include <boost/mpl/and.hpp>
-#include <boost/mpl/not.hpp>
-#include <boost/fusion/container/map.hpp>
-#include <boost/type_traits/is_base_of.hpp>
-
-//[ vtk_mechanism
-
-namespace boost { namespace dataflow { namespace vtk {
-
-// The vtk mechanism tag
-struct mechanism;
-
-} } } // namespace boost::dataflow::vtk
-
-//]
-
-//[ vtk_algorithm_output_producer
-namespace boost { namespace dataflow { namespace vtk {
-
-// PortTraits for vtkAlgorithmOutput objects, which produce data.
-// We specify the Mechanism (vtk::mechanism), PortCategory (ports::producer),
-// and the most refined concept which the port satisfies (ports::port).
-struct vtk_algorithm_output_producer
- : public port_traits<mechanism, ports::producer, concepts::port> {};
-
-} } } // namespace boost::dataflow::vtk
-
-// This macro specializes the port_traits_of template to the specified
-// PortTraits, and also verifies that the PortTraits requirements are satisfied.
-// The port_traits_of template is used by the Dataflow library to associate
-// a Port with its PortTraits.
-DATAFLOW_PORT_TRAITS(vtkAlgorithmOutput, vtk::vtk_algorithm_output_producer)
-//]
-
-
-//[ vtk_algorithm_consumer
-namespace boost { namespace dataflow { namespace vtk {
-
-struct vtk_algorithm_consumer
- : public port_traits<mechanism, ports::consumer, concepts::port> {};
-
-} } } // namespace boost::dataflow::vtk
-
-// Since vtkAlgorithm is typically inherited, we will specialize the
-// port_traits_of template for all its descendants.
-DATAFLOW_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkAlgorithm BOOST_PP_COMMA() T>,
- vtk::vtk_algorithm_consumer)
-//]
-
-//[ vtk_connect_impl_algorithm
-namespace boost { namespace dataflow { namespace extension {
-
-// To implement Connectable, we specialize the binary_operation_impl
-// functor template. We specify three things:
-// operation (operations::connect)
-// producer PortTraits (vtk::vtk_algorithm_output_producer)
-// consumer PortTraits (vtk::vtk_algorithm_consumer)
-template<>
-struct binary_operation_impl<operations::connect, vtk::vtk_algorithm_output_producer, vtk::vtk_algorithm_consumer>
-{
- template<typename Producer, typename Consumer>
- void operator()(Producer &producer, Consumer &consumer)
- {
- consumer.AddInputConnection(&producer);
- }
-};
-
-// To implement OnlyConnectable, we do the same thing except now the operation
-// is operations::connect_only
-template<>
-struct binary_operation_impl<operations::connect_only, vtk::vtk_algorithm_output_producer, vtk::vtk_algorithm_consumer>
-{
- template<typename Producer, typename Consumer>
- void operator()(Producer &producer, Consumer &consumer)
- {
- consumer.SetInputConnection(&producer);
- }
-};
-
-} } } // namespace boost::dataflow::vtk
-
-//]
-
-
-//[ vtk_algorithm_proxy_producer
-
-namespace boost { namespace dataflow { namespace vtk {
-
-// First we need a ProxyPortTraits type
-struct vtk_algorithm_proxy_producer
- : public proxy_port_traits<mechanism, ports::producer> {};
-
-} } } // namespace boost::dataflow::vtk
-
-// Then we associate all descendants of vtkAlgorithm with the ProxyPortTraits.
-// vtkMapper is a descendant of vtkAlgorithm, but we want to exclude it's
-// descendants from this registration because they will be treated differently.
-DATAFLOW_PROXY_PORT_TRAITS_ENABLE_IF(
- T,
- mpl::and_<
- boost::is_base_of<vtkAlgorithm BOOST_PP_COMMA() T> BOOST_PP_COMMA()
- mpl::not_<boost::is_base_of<vtkMapper BOOST_PP_COMMA() T> >
- >,
- vtk::vtk_algorithm_proxy_producer)
-
-namespace boost { namespace dataflow { namespace extension {
-
-// Finally, we specialize the get_port_impl functor template.
- template<>
- struct get_port_impl<vtk::vtk_algorithm_proxy_producer>
- {
- typedef vtkAlgorithmOutput & result_type;
-
- template<typename ProxyProducer>
- result_type operator()(ProxyProducer &t)
- {
- return *t.GetOutputPort();
- }
- };
-
-} } } // namespace boost::dataflow::extension
-
-//]
-
-//[ vtk_actor_filter
-
-namespace boost { namespace dataflow { namespace vtk {
-
-struct vtk_actor_producer
- : public port_traits<mechanism, ports::producer, concepts::port>
-{};
-
-struct vtk_actor_consumer
- : public port_traits<mechanism, ports::consumer, concepts::port>
-{};
-
-} } } // namespace boost::dataflow::vtk
-
-DATAFLOW_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkActor BOOST_PP_COMMA() T>,
- vtk::vtk_actor_producer)
-
-DATAFLOW_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkActor BOOST_PP_COMMA() T>,
- vtk::vtk_actor_consumer)
-
-//]
-
-//[ vtk_mapper_producer
-
-namespace boost { namespace dataflow { namespace vtk {
-
-// First we need a PortTraits type that we will use for vtkMapper connections.
-struct vtk_mapper_producer
- : public port_traits<mechanism, ports::producer, concepts::port> {};
-
-// Since vtkMapper itself will have multiple "faces" (depending on what we
-// are connecting to it), we will define a proxy type for vtkMapper that we
-// will use to specify that we want to use the mapper output for a vtkActor.
-// (rather than wanting to use the output for a vtkAlgorithm, in for which
-// we can use vtkAlgorithmOutput as the proxy object).
-struct vtk_mapper_proxy : public port<vtk_mapper_producer>
-{
- vtkMapper *ptr;
- vtk_mapper_proxy(vtkMapper *mapper) : ptr(mapper) {}
- operator vtkMapper * () const {return ptr;}
-};
-
-// Next, we define a fusion map type to hold the mapping between consumers
-// and Port types.
-typedef boost::fusion::map<
- boost::fusion::pair<vtk::vtk_algorithm_consumer, vtkAlgorithmOutput &>,
- boost::fusion::pair<vtk::vtk_actor_consumer, vtk_mapper_proxy>
- > vtk_mapper_map;
-
-// ...And a ProxyPortTraits type...
-struct vtk_mapper_proxy_producer
- : public proxy_port_traits<
- vtk::mechanism,
- ports::producer
- > {};
-
-} } } // namespace boost::dataflow::vtk
-
-// ... that we associate with vtkMapper descendants.
-DATAFLOW_PROXY_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkMapper BOOST_PP_COMMA() T>,
- vtk::vtk_mapper_proxy_producer)
-
-namespace boost { namespace dataflow { namespace extension {
-
-// Now we specialize the get_port_imple functor template that will return
-// a port_map for a port with vtk_mapper_proxy_producer ProxyPortTraits.
-// The port_map object is a KeyedPort and takes care of providing the
-// appropriate Port depending on the consumer.
-template<>
-struct get_port_impl<vtk::vtk_mapper_proxy_producer>
-{
- typedef const port_map<vtk::mechanism, ports::producer, vtk::vtk_mapper_map> result_type;
-
- template<typename ProxyProducer>
- result_type operator()(ProxyProducer &t)
- {
- return vtk::vtk_mapper_map(t.GetNumberOfOutputPorts() ?
- *t.GetOutputPort() : *(vtkAlgorithmOutput *)NULL,
- vtk::vtk_mapper_proxy(&t));
- }
-};
-
-// Finally, we provide implementations for connect and connect_only
-// between vtk_mapper_producer and vtk_actor_consumer
-template<>
-struct binary_operation_impl<operations::connect_only, vtk::vtk_mapper_producer, vtk::vtk_actor_consumer>
-{
- template<typename Producer, typename Consumer>
- void operator()(Producer &producer, Consumer &consumer)
- {
- consumer.SetMapper(producer);
- }
-};
-
-template<>
-struct binary_operation_impl<operations::connect, vtk::vtk_mapper_producer, vtk::vtk_actor_consumer>
-{
- template<typename Producer, typename Consumer>
- void operator()(Producer &producer, Consumer &consumer)
- {
- BOOST_ASSERT(!consumer.GetMapper());
- consumer.SetMapper(producer);
- }
-};
-
-} } } // namespace boost::dataflow::extension
-
-
-//]
-
-//[ vtk_setup_rest
-
-namespace boost { namespace dataflow { namespace vtk {
-
-struct vtk_renderer_producer
- : public port_traits<mechanism, ports::producer, concepts::port>
-{};
-
-struct vtk_renderer_consumer
- : public port_traits<mechanism, ports::consumer, concepts::port>
-{};
-
-
-struct vtk_rendererwindow_consumer
- : public port_traits<mechanism, ports::consumer, concepts::port>
-{};
-
-} } } // namespace boost::dataflow::vtk
-
-DATAFLOW_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkRenderer BOOST_PP_COMMA() T>,
- vtk::vtk_renderer_producer)
-
-DATAFLOW_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkRenderer BOOST_PP_COMMA() T>,
- vtk::vtk_renderer_consumer)
-
-DATAFLOW_PORT_TRAITS_ENABLE_IF(
- T,
- boost::is_base_of<vtkRenderWindow BOOST_PP_COMMA() T>,
- vtk::vtk_rendererwindow_consumer)
-
-namespace boost { namespace dataflow { namespace extension {
-
-template<>
-struct binary_operation_impl<operations::connect, vtk::vtk_actor_producer, vtk::vtk_renderer_consumer>
-{
- template<typename Producer, typename Consumer>
- void operator()(Producer &producer, Consumer &consumer)
- {
- consumer.AddActor(&producer);
- }
-};
-
-template<>
-struct binary_operation_impl<operations::connect, vtk::vtk_renderer_producer, vtk::vtk_rendererwindow_consumer>
-{
- template<typename Producer, typename Consumer>
- void operator()(Producer &producer, Consumer &consumer)
- {
- consumer.AddRenderer(&producer);
- }
-};
-
-} } } // namespace boost::dataflow::extension
-
-//]
-
-//[ vtk_support_pointer
-
-namespace boost { namespace dataflow {
-
-namespace vtk {
-
- template<typename T>
- struct pointer_proxy_producer : public proxy_port_traits<vtk::mechanism, ports::producer> {};
-
- template<typename T>
- struct pointer_proxy_consumer : public proxy_port_traits<vtk::mechanism, ports::consumer> {};
-
-} // namespace vtk
-
-template<typename T>
-struct proxy_port_traits_of<vtk::mechanism, ports::producer, T *>
-{
- typedef vtk::pointer_proxy_producer<T> type;
-};
-
-template<typename T>
-struct proxy_port_traits_of<vtk::mechanism, ports::consumer, T *>
-{
- typedef vtk::pointer_proxy_consumer<T> type;
-};
-
-namespace extension {
-
- template<typename T>
- struct get_port_impl<vtk::pointer_proxy_producer<T> >
- {
- typedef T & result_type;
-
- template<typename ProxyProducer>
- result_type operator()(ProxyProducer &t)
- {
- return *t;
- }
- };
-
- template<typename T>
- struct get_port_impl<vtk::pointer_proxy_consumer<T> >
- {
- typedef T & result_type;
-
- template<typename ProxyConsumer>
- result_type operator()(ProxyConsumer &t)
- {
- return *t;
- }
- };
-
-} // namespace extension
-
-} } // namespace boost::dataflow
-
-//]
-
-//[ vtk_specialize_connect
-// the include templates expect DATAFLOW_TEMPLATE_MECHANISM to have
-// the template type
-#define DATAFLOW_TEMPLATE_MECHANISM boost::dataflow::vtk::mechanism
-
-// the binary_operation.hpp template expects DATAFLOW_TEMPLATE_BINARY_OPERATION
-#define DATAFLOW_TEMPLATE_BINARY_OPERATION connect
-#include <boost/dataflow/templates/binary_operation.hpp>
-#undef DATAFLOW_TEMPLATE_BINARY_OPERATION
-
-#define DATAFLOW_TEMPLATE_BINARY_OPERATION connect_only
-#include <boost/dataflow/templates/binary_operation.hpp>
-#undef DATAFLOW_TEMPLATE_BINARY_OPERATION
-
-#undef DATAFLOW_TEMPLATE_MECHANISM
-// We now have connect and connect_only functions that each take a
-// vtk ProducerPort and vtk ConsumerPort as arguments, and try to connect them.
-//]
-
-#endif // BOOST_DATAFLOW_VTK_SUPPORT_HPP
\ No newline at end of file
Copied: sandbox/SOC/2007/signals/libs/dataflow/example/VTK/vtk_dataflow_support.hpp (from r41018, /sandbox/SOC/2007/signals/libs/dataflow/example/VTK/support.hpp)
==============================================================================
--- /sandbox/SOC/2007/signals/libs/dataflow/example/VTK/support.hpp (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/VTK/vtk_dataflow_support.hpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -377,21 +377,37 @@
//[ vtk_specialize_connect
// the include templates expect DATAFLOW_TEMPLATE_MECHANISM to have
-// the template type
+// the mechanism type
#define DATAFLOW_TEMPLATE_MECHANISM boost::dataflow::vtk::mechanism
// the binary_operation.hpp template expects DATAFLOW_TEMPLATE_BINARY_OPERATION
-#define DATAFLOW_TEMPLATE_BINARY_OPERATION connect
-#include <boost/dataflow/templates/binary_operation.hpp>
-#undef DATAFLOW_TEMPLATE_BINARY_OPERATION
-
-#define DATAFLOW_TEMPLATE_BINARY_OPERATION connect_only
-#include <boost/dataflow/templates/binary_operation.hpp>
-#undef DATAFLOW_TEMPLATE_BINARY_OPERATION
+# define DATAFLOW_TEMPLATE_BINARY_OPERATION connect
+# include <boost/dataflow/templates/binary_operation.hpp>
+
+// the operator.hpp template expects DATAFLOW_TEMPLATE_OPERATOR
+# define DATAFLOW_TEMPLATE_OPERATOR >>=
+# include <boost/dataflow/templates/operator.hpp>
+# undef DATAFLOW_TEMPLATE_OPERATOR
+
+# undef DATAFLOW_TEMPLATE_BINARY_OPERATION
+
+# define DATAFLOW_TEMPLATE_BINARY_OPERATION connect_only
+# include <boost/dataflow/templates/binary_operation.hpp>
+
+# define DATAFLOW_TEMPLATE_OPERATOR ^=
+# include <boost/dataflow/templates/operator.hpp>
+# undef DATAFLOW_TEMPLATE_OPERATOR
+
+# undef DATAFLOW_TEMPLATE_BINARY_OPERATION
#undef DATAFLOW_TEMPLATE_MECHANISM
+
// We now have connect and connect_only functions that each take a
// vtk ProducerPort and vtk ConsumerPort as arguments, and try to connect them.
+
+// We also have operators >>= for the connect operation,
+// and ^= for the connect_only operation.
+
//]
#endif // BOOST_DATAFLOW_VTK_SUPPORT_HPP
\ No newline at end of file
Modified: sandbox/SOC/2007/signals/libs/dataflow/example/signals/Jamfile.v2
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/signals/Jamfile.v2 (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/signals/Jamfile.v2 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -16,4 +16,4 @@
/boost/serialization//boost_serialization/<link>static
/boost/thread//boost_thread/<link>static
/boost/system//boost_system/<link>static ;
-
+exe gil_example : gil_example.cpp /boost/thread//boost_thread/<link>static ;
Added: sandbox/SOC/2007/signals/libs/dataflow/example/signals/gil_example.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/signals/gil_example.cpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -0,0 +1,228 @@
+// Copyright 2007 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)
+
+//[ gil_example_preliminary
+
+#include <boost/dataflow/signals/component/timed_generator.hpp>
+#include <boost/dataflow/signals/component/multiplexer.hpp>
+#include <boost/dataflow/signals/connection.hpp>
+
+#include <boost/gil/gil_all.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/variate_generator.hpp>
+
+using namespace boost;
+
+//]
+
+
+//[ gil_example_image_generator
+
+class image_generator : public signals::filter<void(const gil::gray8_image_t &)>
+{
+public:
+ // constructed with the width, height, and initial grayscale value of the image
+ image_generator(unsigned width, unsigned height, int value)
+ : image(width, height), value(value) {}
+
+ // Upon receiving a void() signal, build and output the image
+ void operator()()
+ {
+ boost::gil::fill_pixels(view(image), value);
+ out(image);
+ }
+ // Upon receiving a void(int) signal, set the grayscale value to what's received
+ void operator()(int new_value)
+ {
+ value = new_value;
+ }
+private:
+ gil::gray8_image_t image;
+ int value;
+};
+
+//]
+
+//[ gil_example_noise_adder
+
+class noise_adder : public signals::filter<void(const gil::gray8_image_t &)>
+{
+public:
+ noise_adder() : dist(0, 10), generator(mt, dist)
+ {}
+ // Upon receiving an image, generate the filtered version and output it.
+ void operator()(const gil::gray8_image_t &image)
+ {
+ if (image.dimensions() != filtered_image.dimensions())
+ filtered_image.recreate(image.dimensions());
+ boost::gil::transform_pixels(
+ const_view(image),
+ view(filtered_image),
+ transformer(generator));
+ out(filtered_image);
+ }
+private:
+ gil::gray8_image_t filtered_image;
+
+ mt19937 mt;
+ normal_distribution<> dist;
+ variate_generator<mt19937&, boost::normal_distribution<> > generator;
+
+ struct transformer
+ {
+ transformer(variate_generator<mt19937&, boost::normal_distribution<> > &generator)
+ : generator(generator)
+ {}
+
+ gil::gray8_pixel_t operator()(const gil::gray8_pixel_t& p) const
+ {
+ return gil::gray8_pixel_t(p + generator());
+ }
+
+ variate_generator<mt19937&, boost::normal_distribution<> > &generator;
+ };
+};
+
+//]
+
+//[ gil_example_image_display
+
+class image_display
+{
+public:
+ typedef dataflow::signals::call_consumer port_traits;
+
+ // Upon receiving an image, cout an ASCII approximation.
+ void operator()(const gil::gray8_image_t &image)
+ {
+ gil::gray8_image_t::const_view_t view = const_view(image);
+ for (int y=0; y<view.height(); y++)
+ {
+ gil::gray8_image_t::const_view_t::x_iterator it = view.row_begin(y);
+
+ for (int x=0; x<view.width(); x++)
+ std::cout << symbols[it[x] * (sizeof(symbols) / sizeof(char)) / 256];
+ std::cout << std::endl;
+ }
+ std::cout << std::endl;
+ }
+private:
+ static char symbols[8];
+};
+
+char image_display::symbols[8] = {' ', '.', ',', ':', ';', '*', '#', '$' };
+
+//]
+
+//[ gil_example_controller
+
+class controller
+{
+public:
+ controller(int value) : value(value) {}
+
+ void run()
+ {
+ while (!std::cin.eof() && !std::cin.fail())
+ {
+ int key = std::cin.get();
+ switch (key)
+ {
+ // Keys ',' and '.' adjust the grayscale value
+ case ',':
+ adjust(-20);
+ break;
+ case '.':
+ adjust(20);
+ break;
+ // Keys '0' and '1' control the mux output
+ case '0':
+ select_signal(0);
+ break;
+ case '1':
+ select_signal(1);
+ break;
+ // 'q' quits.
+ case 'q':
+ return;
+ }
+ }
+ }
+
+ boost::signal<void(int)> value_signal;
+ boost::signal<void(int)> select_signal;
+private:
+ void adjust(int delta)
+ {
+ value += delta;
+ if (value < 0) value = 0;
+ if (value > 255) value = 255;
+ value_signal(value);
+ }
+ int value;
+};
+
+//]
+
+//[ gil_example_main
+
+int main(int, char* [])
+{
+ // To drive the dataflow network, we will use timed_generator,
+ // which creates its own thread and outputs a signal
+ // at a specified time interval. We'll store a value of 0 to be sent out.
+ // The signature void() specifies that the signal is empty - we just
+ // use it to drive the network.
+ signals::timed_generator<void ()> timer;
+
+ // Data processor and output:
+ image_generator generator(10,10, 128);
+ noise_adder filter;
+ image_display display;
+
+ controller control(128);
+ signals::multiplexer<void (const gil::gray8_image_t &)> mux;
+
+ // ---Connect the dataflow network -----------------------------------------
+ //
+ // ,---------.
+ // | control | -----------------------+
+ // `---------' |
+ // | |
+ // v v
+ // ,-------. ,-----------. ,-------.
+ // | timer | --> | generator | -+--------------> 0 | ,---------.
+ // `-------' `-----------' | | mux | -> | display |
+ // | ,--------. | | `---------'
+ // +->| filter |--> 1 |
+ // `--------' `-------'
+ //
+ // -------------------------------------------------------------------------
+ timer >>= generator | mux.slot<0>()
+ | (filter >>= mux.slot<1>());
+
+ mux >>= display;
+
+ control.value_signal >>= generator;
+ control.select_signal >>= mux.select_slot();
+
+ // Tell the timer to start producing signals, every 0.5s:
+ timer.enable(0.5);
+
+ // Run the controller
+ std::cout
+ << "Use keys ',' and '.' to control the image intensity, "
+ << "and '0' and '1' to switch the display between the unfiltered"
+ << "and filtered image. 'q' will exit." << std::endl
+ << "Since we are using cin for the input, REMEMBER TO PRESS ENTER"
+ << "after each command.";
+ control.run();
+
+ timer.join();
+ return 0;
+}
+
+//]
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 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -18,5 +18,6 @@
run test_binary_op.cpp ;
run test_keyed_port.cpp ;
run test_component.cpp ;
+run test_reflective_component.cpp ;
build-project signals ;
Modified: sandbox/SOC/2007/signals/libs/dataflow/test/test_component.cpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/test/test_component.cpp (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/test_component.cpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -4,6 +4,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/dataflow/support/component_operation.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
bool invoked = false;
Modified: sandbox/SOC/2007/signals/libs/dataflow/test/test_port.cpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/test/test_port.cpp (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/test_port.cpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -7,6 +7,115 @@
#include <boost/test/included/test_exec_monitor.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+// for different port registrations
+
+//[ port_registration_example_prep
+struct some_mechanism;
+
+typedef df::port_traits<some_mechanism, df::ports::producer, df::concepts::port> producer_traits;
+typedef df::port_traits<some_mechanism, df::ports::consumer, df::concepts::port> consumer_traits;
+
+//]
+
+//[ port_registration_example_intrusive
+
+// Intrusive registration of a single port
+struct intrusive_producer_port
+{
+ // intrusive_producer_port is a ProducerPort
+ typedef producer_traits port_traits;
+};
+
+// Intrusive registration of multiple ports
+struct intrusive_producer_consumer_port
+{
+ // intrusive_filter_port is a ProducerPort and a ConsumerPort
+ typedef boost::mpl::vector<producer_traits, consumer_traits> port_traits;
+};
+//]
+
+//[ port_registration_example_non_intrusive
+
+struct non_intrusive_port
+{
+// Can't or don't want to modify the type
+};
+
+namespace boost { namespace dataflow {
+
+// port_traits_of holds the PortTraits type of a Port, keyed by Mechanism
+// and PortCategory
+template<>
+struct port_traits_of<some_mechanism, df::ports::producer, non_intrusive_port>
+{
+ typedef producer_traits type;
+};
+
+} } // namespace boost::dataflow
+
+//]
+
+//[ port_registration_example_non_intrusive_macro
+
+// Non-intrusive registration via a macro:
+struct non_intrusive_port2
+{
+// Can't or don't want to modify the type
+};
+
+DATAFLOW_PORT_TRAITS(non_intrusive_port2, producer_traits)
+
+//]
+
+//[ port_registration_example_non_intrusive_enable_if
+
+// Non-intrusive registration via an enable_if expression
+struct non_intrusive_port_base
+{
+};
+
+namespace boost { namespace dataflow {
+
+// port_traits_of holds the PortTraits type of a Port, keyed by Mechanism
+// and PortCategory
+template<typename T>
+struct port_traits_of<
+ some_mechanism,
+ df::ports::producer,
+ T,
+ typename boost::enable_if<
+ boost::is_base_of<non_intrusive_port_base, T>
+ >::type>
+{
+ typedef producer_traits type;
+};
+
+} } // namespace boost::dataflow
+
+struct non_intrusive_port_descendant : public non_intrusive_port_base
+{};
+
+//]
+
+//[ port_registration_example_non_intrusive_enable_if_macro
+
+// Non-intrusive registration via a macro and an enable_if expression
+struct non_intrusive_port_base2
+{
+};
+
+DATAFLOW_PORT_TRAITS_ENABLE_IF(
+ T,
+ boost::is_base_of<non_intrusive_port_base2 BOOST_PP_COMMA() T>,
+ producer_traits)
+
+struct non_intrusive_port_descendant2 : public non_intrusive_port_base2
+{};
+
+//]
int test_main(int, char* [])
{
@@ -38,5 +147,20 @@
BOOST_CHECK_EQUAL(&cp, (&df::get_port<my_mechanism, df::ports::producer>(cp)));
BOOST_CHECK(( boost::is_same<df::get_port_result_type<my_mechanism, df::ports::producer, const volatile my_producer>::type, const volatile my_producer &>::value ));
+ // check registrations
+ //[ port_registration_check_example
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::producer, intrusive_producer_port>::value ));
+
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::producer, intrusive_producer_consumer_port>::value ));
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::consumer, intrusive_producer_consumer_port>::value ));
+
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::producer, non_intrusive_port>::value ));
+
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::producer, non_intrusive_port2>::value ));
+
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::producer, non_intrusive_port_descendant>::value ));
+
+ BOOST_CHECK(( df::is_port<some_mechanism, df::ports::producer, non_intrusive_port_descendant2>::value ));
+ //]
return 0;
} // int test_main(int, char* [])
Added: sandbox/SOC/2007/signals/libs/dataflow/test/test_reflective_component.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/test/test_reflective_component.cpp 2007-11-14 00:38:58 EST (Wed, 14 Nov 2007)
@@ -0,0 +1,83 @@
+// Copyright Stjepan Rajko 2007. 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/support/reflective_component.hpp>
+//#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/int.hpp>
+
+#include "my_producer_consumer.hpp"
+
+struct my_component_traits
+{
+ typedef my_mechanism mechanism;
+ typedef
+ boost::mpl::vector<
+ my_consumer_traits,
+ my_producer_traits
+ > ports;
+};
+
+struct my_component
+{
+ typedef my_component_traits component_traits;
+
+ my_consumer consumer;
+ my_producer producer;
+};
+
+namespace boost { namespace dataflow { namespace extension {
+
+template<>
+struct get_component_port_impl<my_component_traits>
+{
+ template<typename FArgs> struct result;
+
+ template<typename F, typename Component>
+ struct result<F(Component &, boost::mpl::int_<0>)>
+ {
+ typedef my_consumer & type;
+ };
+
+ template<typename F, typename Component>
+ struct result<F(Component &, boost::mpl::int_<1>)>
+ {
+ typedef my_producer & type;
+ };
+
+ template<typename Component>
+ my_consumer &
+ operator()(Component &component, boost::mpl::int_<0>)
+ {
+ return component.consumer;
+ }
+
+ template<typename Component>
+ my_producer &
+ operator()(Component &component, boost::mpl::int_<1>)
+ {
+ return component.producer;
+ }
+};
+
+}}}
+
+#include <boost/test/included/test_exec_monitor.hpp>
+
+namespace df = boost::dataflow;
+
+int test_main(int, char* [])
+{
+ my_component c;
+
+ my_consumer &cc = df::get_component_port<my_mechanism, boost::mpl::int_<0> >(c);
+ my_producer &cp = df::get_component_port<my_mechanism, boost::mpl::int_<1> >(c);
+
+ BOOST_CHECK_EQUAL(&cc, &c.consumer);
+ BOOST_CHECK_EQUAL(&cp, &c.producer);
+
+ 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