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


Next

Setting up the remaining components (more of the same)