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 KeyedPorts,
which delegate fuctionality to a Port
determined by the Port
they are being connected to.
namespace boost { namespace dataflow { namespace vtk { // First we need a PortTraits type that we will use for vtkMapper connections. struct vtk_mapper_producer : public complemented_port_traits<ports::producer, dataflow::port_adapter<vtkActor, vtk_actor_producer, tag>, tag> {}; // 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, port_adapter<vtkMapper, vtk_mapper_producer, tag> > > vtk_mapper_map; // ...And a ComponentTraits type... template<typename T> struct vtk_mapper_component_traits : public dataflow::fusion_component_traits< fusion::vector< fusion_keyed_port<ports::producer, vtk::vtk_mapper_map, tag>, vtk_algorithm_consumer_adapter >, detail::default_map, tag> { template<typename Component> static typename vtk_mapper_component_traits::fusion_ports get_ports(Component &c) { return typename vtk_mapper_component_traits::fusion_ports( fusion_keyed_port<dataflow::ports::producer, vtk::vtk_mapper_map, tag>( vtk::vtk_mapper_map(c.GetNumberOfOutputPorts() ? *c.GetOutputPort() : *(vtkAlgorithmOutput *)NULL, port_adapter<vtkMapper, vtk_mapper_producer, tag>(c))), c); } }; } } } // namespace boost::dataflow::vtk // ... that we associate with vtkMapper descendants. DATAFLOW_TRAITS_ENABLE_IF( T, boost::is_base_of<vtkMapper BOOST_PP_COMMA() T>, vtk::vtk_mapper_component_traits<T>) namespace boost { namespace dataflow { namespace extension { // Finally, we provide implementations for connect and connect_only // between vtk_mapper_producer and vtk_actor_consumer template<> struct binary_operation_impl<vtk::vtk_mapper_producer, vtk::vtk_actor_consumer, operations::connect_only> { typedef void result_type; template<typename Producer, typename Consumer> void operator()(Producer &producer, Consumer &consumer) { consumer.SetMapper(producer); } }; template<> struct binary_operation_impl<vtk::vtk_mapper_producer, vtk::vtk_actor_consumer, operations::connect> { typedef void result_type; template<typename Producer, typename Consumer> void operator()(Producer &producer, Consumer &consumer) { BOOST_ASSERT(!get_object(consumer).GetMapper()); get_object(consumer).SetMapper(&get_object(producer)); } }; } } } // namespace boost::dataflow::extension