Examples in Event Dispatching, Page 2
The Refinement
A more sophisticated example is presented in the next code excerpt:
namespace RelayGenerator2
{
template <class R, template <class T> class D = Relay>
struct RGBase
{
typedef D< typename R::RELAY > DISPATCHER;
typedef Relay<DISPATCHER > RELAY;
static RELAY getRelay()
{
return RELAY(DISPATCHER(R::getRelay()));
}
};
template <class R >
struct RGBase<R, Relay>
{
typedef R DISPATCHER;
typedef Relay<DISPATCHER > RELAY;
static RELAY getRelay()
{
return RELAY(R());
}
};
template <int I>
struct RG
{
typedef void DISPATCHER;
};
template <>
struct RG<0> : RGBase<BasicLayerDispatcher>
{ };
template <>
struct RG<1> : RGBase<RG<0>, SecondLayerDispatcher >
{ };
template <>
struct RG<2> : RGBase< RG<1>, ThirdLayerDispatcher>
{};
template <int L, class E>
void relay(const E& e)
{
RG<L>::getRelay().relay(e);
}
template <int I>
struct IsValidRG
{
typedef char ONE;
typedef struct {char a[2];} TWO;
template <class C>
static ONE isClass(...);
template <class C>
static TWO isClass(int C::*);
enum E {
e=sizeof(isClass<typename RG<I>::DISPATCHER>(0) )
== 2 ? IsValidRG<I+1>::e : I-1
};
};
template <>
struct IsValidRG<200>
{
enum E {
e
};
};
template <class E>
void broadcast(const E& e)
{
relay<IsValidRG<0>::e>(e);
}
void action()
{
}
The first observation is that RG was factored out using RGBase. The second and more important observation is that a broadcast method was implemented. As mentioned in Note 2, broadcast is automatically achieved by dispatching to the last Relay of the chain. A method of automatically finding the last specialization of a Relay (isValidRG) is based on the SFINAE (Substitution Failure Is Not An Error [2]) concept and the remark that RG::DISPATCHER is a class for all the cases when RG is a specialization and otherwise not.
Where You Are
I presented two multilayered Event Dispatching implementations, together with a design overview. Single- and multilayered designs were compared and their complementary was underlined. With minimal effort, the reader can either combine the two approaches or use one at a time only.
Download the Code
You can download the code that accompanies this article here.
References
- Event Dispatching: One Size Doesn't Fit All: Part 1
- C++ Templates: The Complete Guide.
Nicolai M. Josuttis. Addison-Wesley, 2002
