00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef IH_SENF_PPI_Route_
00027 #define IH_SENF_PPI_Route_ 1
00028
00029
00030 #include <boost/type_traits/is_convertible.hpp>
00031 #include <boost/type_traits/is_base_of.hpp>
00032 #include <boost/mpl/if.hpp>
00033 #include <boost/mpl/bool.hpp>
00034 #include <boost/static_assert.hpp>
00035
00036
00037
00038 #ifndef DOXYGEN
00039
00040 namespace senf {
00041 namespace ppi {
00042 namespace detail {
00043
00044
00045
00046 template <class Connector, bool isEvent>
00047 struct RoutingTraitsImplementation
00048 {
00049 BOOST_STATIC_ASSERT((boost::is_base_of<connector::Connector, Connector>::value));
00050
00051 static bool const event = false;
00052
00053 static bool const notifySource = boost::is_base_of<
00054 connector::ActiveConnector, Connector>::value;
00055 static bool const notifyTarget = boost::is_base_of<
00056 connector::PassiveConnector, Connector>::value;
00057
00058 static bool const dataSource = boost::is_base_of<
00059 connector::InputConnector, Connector>::value;
00060 static bool const dataTarget = boost::is_base_of<
00061 connector::OutputConnector, Connector>::value;
00062
00063 typedef Connector type;
00064 };
00065
00066
00067
00068 template <class Event>
00069 struct RoutingTraitsImplementation<Event,true>
00070 {
00071 static bool const event = true;
00072
00073 static bool const notifySource = false;
00074 static bool const notifyTarget = true;
00075
00076 static bool const dataSource = true;
00077 static bool const dataTarget = true;
00078
00079 typedef EventDescriptor type;
00080 };
00081
00082
00083
00084
00085
00086
00087
00088
00089 template <class Object>
00090 struct RoutingTraits
00091 : public RoutingTraitsImplementation<Object,
00092 boost::is_convertible<Object*,
00093 EventDescriptor*>::value>
00094 {};
00095
00096
00097
00098 template <class Source, class Target, class Base>
00099 class BaseRouteImplementation
00100 : public Base
00101 {
00102 public:
00103 typedef Source source_type;
00104 typedef Target target_type;
00105
00106 Source & source() const;
00107 Target & target() const;
00108
00109 protected:
00110 BaseRouteImplementation(module::Module & module, Source & source, Target & target);
00111
00112 private:
00113 bool v_hasConnector(connector::Connector const & conn) const;
00114 bool v_hasEvent(EventDescriptor const & event) const;
00115
00116 bool isSame(connector::Connector const & conn, connector::Connector const & other) const;
00117 bool isSame(connector::Connector const & conn, EventDescriptor const & other) const;
00118 bool isSame(EventDescriptor const & event, connector::Connector const & other) const;
00119 bool isSame(EventDescriptor const & event, EventDescriptor const & other) const;
00120
00121 Source * source_;
00122 Target * target_;
00123 };
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 template <class Source, class Target>
00139 class ForwardingRouteImplementation
00140 : public BaseRouteImplementation<Source, Target, ForwardingRoute>
00141 {
00142 typedef BaseRouteImplementation<Source, Target, ForwardingRoute> Base;
00143
00144 protected:
00145 ForwardingRouteImplementation(module::Module & module, Source & source, Target & target);
00146 ~ForwardingRouteImplementation();
00147
00148 private:
00149
00150 template <class T> void notifyThrottle(T & ob, boost::mpl::bool_<true> const &);
00151 template <class T> void notifyThrottle(T & ob, boost::mpl::bool_<false> const &);
00152 template <class T> void notifyUnthrottle(T & ob, boost::mpl::bool_<true> const &);
00153 template <class T> void notifyUnthrottle(T & ob, boost::mpl::bool_<false> const &);
00154
00155 template <class T> bool throttled(T & ob, boost::mpl::bool_<true> const &) const;
00156 template <class T> bool throttled(T & ob, boost::mpl::bool_<false> const &) const;
00157
00158 virtual void v_notifyThrottle();
00159 virtual void v_notifyUnthrottle();
00160 virtual bool v_throttled() const;
00161 };
00162
00163
00164
00165
00166
00167
00168
00169 template <class Source, class Target>
00170 struct RouteImplementationBase
00171 {
00172 typedef RoutingTraits<Source> srcTrait;
00173 typedef RoutingTraits<Target> trgTrait;
00174
00175 static bool const isForwarding = (srcTrait::notifySource && trgTrait::notifyTarget)
00176 || (srcTrait::notifyTarget && trgTrait::notifySource);
00177
00178 typedef typename boost::mpl::if_c<
00179 isForwarding,
00180 ForwardingRouteImplementation<Source,Target>,
00181 BaseRouteImplementation<Source,Target,RouteBase> >::type base;
00182 };
00183
00184
00185
00186
00187 template <class Source, class Target>
00188 class RouteImplementation2
00189 : public RouteImplementationBase<Source,Target>::base
00190 {
00191 typedef typename RouteImplementationBase<Source,Target>::base Base;
00192
00193 BOOST_STATIC_ASSERT( RoutingTraits<Source>::dataSource &&
00194 RoutingTraits<Target>::dataTarget );
00195
00196 protected:
00197 RouteImplementation2(module::Module & module, Source & source, Target & target);
00198 };
00199
00200
00201
00202
00203 template <class Source, class Target>
00204 class RouteImplementation
00205 : public RouteImplementation2<typename RoutingTraits<Source>::type,
00206 typename RoutingTraits<Target>::type>
00207 {
00208 typedef RouteImplementation2<typename RoutingTraits<Source>::type,
00209 typename RoutingTraits<Target>::type> Base;
00210
00211 protected:
00212 RouteImplementation(module::Module & module, Source & source, Target & target);
00213 };
00214
00215 }}}
00216
00217 #endif
00218
00219
00220 #endif
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231