Use event dispatcher as a substitution of switch case
Switch case==Evil?
Switch case is not neccessary to be evil until it is used to deal with complicated logic. unfortunatly, there is a sweeping trend in my company to put "if else" or another inner switch case inside a case. Then the function turns out to be an unreadable big function. In addition, big function will cause stack overflow when there are too many variables in it. Here is an example:
switch(){
case : {
if{}
else {
if {}
}
}
break;
case :{
switch() {
case :
}
}
}
mechanism of dispatcher
the mechanism of event dispatcher is function register and member function call back. When calling a member function of a object, we need
the pointer of object "this"
the pointer of member function.
and the type of parameters.
Here is an sample: pThis->*pMemberFunction(parameters)
implementation
template class Dispather{
typedef void(ClassOfFunction::*MemberFunctionPtr)(Parameters parameters);
typedef Parameters ParametersType;
void SetObjOfFunction(ClassOfFunction* pThis){
m_pThis = pThis;
}
void Insert(Event event,MemberFunctionPtr memberFunPtr);
void Dispatch(Event event,Parameters params){
MemberFunctionPtr memberFunPtr = m_dispatcherTable.find(event);
m_pThis->*memberFunPtr(params);
}
Table m_dispatcherTable;
ClassOfFunctions* m_pThis;
};
usage
class MyParameters{
FieldA& fieldA;
FieldB& fieldB;
}; class Foo{
Foo(){
m_dispatcher.SetObjOfFunction(this);
m_dispatcher.Insert(XXEvent,&Foo::OnXXEvent);
}
void OnXXEvent(MyParameters params);
void RecvMsg(Message& message){
MyParameters params(message);
m_dispatcher.Dispatch(message.event,params);
}
Dispather m_dispatcher;
};
use macros to simplify
#define DISPATCHER_DECLEARATION(className,parameters)\ Dispather m_dispatcher;\ typedef Dispather::MemberFunctionPtr MsgFunctionPtr; \ typedef Dispather::ParametersType ParametersType
#define DISPATCHER_INIT() this->m_dispatcher.SetObjOfFunction(this)
#define DISPATCHER_INSERT(event,theFunction) this->m_dispatcher.Insert(event,theFunction)
#define DISPATCH(event,parameters) this->m_dispatcher.Dispatch(event,parameters);
use compile-time facilities to enhance macros
use do while to limit scope and use static_cast to ensure type-safe.
#define DISPATCHER_INIT()\
do{\
this->m_msgDispatcher.SetObjOfFunction(this);\
}while(0)
#define DISPATCHER_INSERT(event,theFunction)\
do{\
this->m_dispatcher.Insert(static_cast(event),static_cast(theFunction));\
}while(0)
#define DISPATCH(event,parameters)\
this->m_dispatcher.Dispatch(static_cast<Event>(event),static_cast(parameters));













