/********************************************************************
author : Clark/陈泽丹
created : 2014-4-22
purpose : 双分派文件
本想用暴力模板双分派解决就好了,因为类型不过五六个,但每每动笔时就有一个
幽灵般的声音在回荡:暴力法的遍历开销XXX... 这个声音谁发的?呃,你懂的。
纠结一会后决定还是费力点用map表解决算了,毕竟这是服务器,能省开销就省些吧。
其实就这种查多删少的操作,还可以用SortedVector类再进一步压榨性能。
但想想哥只是个写脚本的,还是老实点好...
*********************************************************************/
#pragma once
#include <map>
#include <algorithm>
using namespace std;
template< class _SIGN, class _BL, class _BR >
class CommonDispatcher
{
public:
virtual ~CommonDispatcher()
{
auto Clear = []( pair<KEY_TYPE const, FunImpl*> _item ) -> void
{
if( NULL != _item.second )
{
delete _item.second;
_item.second = NULL;
}
};
for_each( m_dispatch_map.begin(), m_dispatch_map.end(), Clear );
m_dispatch_map.clear();
}
//注册功能
template< int _L, int _R, class _Fun >
void Regist( const _Fun& _fun )
{
class Adapter: public FunImpl
{
public:
Adapter(const _Fun& _fun):fun(_fun){}
virtual void operator()( _BL *_pl, _BR *_pr )
{
fun( _pl, _pr );
}
private:
_Fun fun;
};
KEY_TYPE key = make_pair(_L,_R);
m_dispatch_map[key] = new Adapter(_fun);
}
//派发
void operator()( _BL *_pl, _BR *_pr )
{
if( NULL != _pl && NULL != _pr )
{
KEY_TYPE key = make_pair(_pl->GetType(),_pr->GetType());
auto it = m_dispatch_map.find( key );
if( m_dispatch_map.end() != it )
{
int k = 0;
(*(it->second))(_pl,_pr);
}
}
}
private:
struct FunImpl
{
virtual void operator()( _BL *_pl, _BR *_pr ) = NULL;
};
typedef pair<long,long> KEY_TYPE;
map< KEY_TYPE, FunImpl* > m_dispatch_map;
};
struct BaseMoveRune{};
struct BaseL
{
virtual long GetType(){ return 2; }
};
struct BaseR
{
virtual long GetType(){ return 2; }
};
struct Test
{
void operator()( BaseL* _pl, BaseR *_pr )
{
int k = 0;
}
};
CommonDispatcher< BaseMoveRune, BaseL, BaseR > m_dispatcher;
Test test;
m_dispatcher.Regist<1,2>(test);
BaseL l;
BaseR r;
m_dispatcher( &l, &r );