您的位置:首页 > 编程语言 > C语言/C++

C++中事件机制的简洁实现及需要放弃的特性

2013-02-01 14:54 986 查看

View Code
#pragma once
#include <map>
#include <functional>
namespace Utility
{
namespace Private
{
struct NullType {};
template<class HandlerT>
class EventBase
{
public:
EventBase() : m_handlerId(0) {}
template<class FuncT> int addHandler(FuncT func)
{
m_handlers.emplace(m_handlerId, std::forward<FuncT>(func));
return m_handlerId++;
}
void removeHandler(int handlerId)
{
m_handlers.erase(handlerId);
}
protected:
int m_handlerId;
std::map<int, std::function<HandlerT>> m_handlers;
};
}
template<class P1 = Private::NullType, class P2 = Private::NullType, class P3 = Private::NullType, class P4 = Private::NullType, class P5 = Private::NullType, class P6 = Private::NullType, class P7 = Private::NullType, class P8 = Private::NullType, class P9 = Private::NullType, class P10 = Private::NullType>
class Event
: public Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4, _5, _6, _7, _8, _9, _10));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6, P7 arg7, P8 arg8, P9 arg9, P10 arg10)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
}
};
template<>
class Event<Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void ()>
{
public:
using Private::EventBase<void ()>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT const obj, FuncT func)
{
m_handlers.emplace(m_handlerId, std::bind(func, obj));
return m_handlerId++;
}
void operator ()()
{
for ( const auto& i : m_handlers )
i.second();
}
};
template<class P1>
class Event<P1, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1)>
{
public:
using Private::EventBase<void (P1)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1));
return m_handlerId++;
}
void operator ()(P1 arg1)
{
for ( const auto& i : m_handlers )
i.second(arg1);
}
};
template<class P1, class P2>
class Event<P1, P2, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2)>
{
public:
using Private::EventBase<void (P1, P2)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2);
}
};
template<class P1, class P2, class P3>
class Event<P1, P2, P3, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2, P3)>
{
public:
using Private::EventBase<void (P1, P2, P3)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3);
}
};
template<class P1, class P2, class P3, class P4>
class Event<P1, P2, P3, P4, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2, P3, P4)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4);
}
};
template<class P1, class P2, class P3, class P4, class P5>
class Event<P1, P2, P3, P4, P5, Private::NullType, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2, P3, P4, P5)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4, P5)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4, _5));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4, arg5);
}
};
template<class P1, class P2, class P3, class P4, class P5, class P6>
class Event<P1, P2, P3, P4, P5, P6, Private::NullType, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2, P3, P4, P5, P6)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4, P5, P6)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4, _5, _6));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4, arg5, arg6);
}
};
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7>
class Event<P1, P2, P3, P4, P5, P6, P7, Private::NullType, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4, _5, _6, _7));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6, P7 arg7)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
};
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
class Event<P1, P2, P3, P4, P5, P6, P7, P8, Private::NullType, Private::NullType>
: public Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7, P8)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7, P8)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4, _5, _6, _7, _8));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6, P7 arg7, P8 arg8)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
}
};
template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
class Event<P1, P2, P3, P4, P5, P6, P7, P8, P9, Private::NullType>
: public Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7, P8, P9)>
{
public:
using Private::EventBase<void (P1, P2, P3, P4, P5, P6, P7, P8, P9)>::addHandler;
template<class ObjT, class FuncT> int addHandler(ObjT obj, FuncT func)
{
using namespace std::placeholders;
m_handlers.emplace(m_handlerId, std::bind(func, std::forward<ObjT>(obj), _1, _2, _3, _4, _5, _6, _7, _8, _9));
return m_handlerId++;
}
void operator ()(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6, P7 arg7, P8 arg8, P9 arg9)
{
for ( const auto& i : m_handlers )
i.second(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
}
};
} // namespace Utility
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  事件 机制 模型