当事件触发(按键,鼠标等)时,我的应用程序将调用已注册该事件的委托函数。
以下是实施。我试图让'invoke'函数(()
)成为一个可变参数模板,以便我可以将任何参数传递给它。但是我目前的设置不可能。
我在设计中如何使用可变参数模板的任何想法?
修改更改的代码
template <typename... params>
class EventDelegate
{
public:
typedef std::function<int(params...)> EDelegate;
EventDelegate(EDelegate delegate) : delegate(delegate)
{
}
int operator()(params...) const
{
return delegate(params...);
}
private:
EDelegate delegate;
};
// Not valid because template params are not specified. But each EventDelegate can take different params
std::unordered_multimap<int, EventDelegate> evtRegistry;
// Example
class Foo
{
public:
int onLeftClick(GUID sender, Point pos);
int onKeyDown(char key);
};
// Usage
...
evtRegistry[1] = EventDelegate(std::bind(&Foo::onLeftClick, myFoo, std::placeholders::_1, std::placeholders::_2));
evtRegistry[2] = EventDelegate(std::bind(&Foo::onKeyDown, myFoo, std::placeholders::_1));
事件处理:
LRESULT CALLBACK Win32App::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
auto registeredCmps = evtRegistry.equal_range(EVT_INIT);
for (auto iter = registeredCmps.first; iter != registeredCmps.second; iter++)
iter->second();
}
break;
case WM_DESTROY:
{
auto registeredCmps = evtRegistry.equal_range(EVT_EXIT);
for (auto iter = registeredCmps.first; iter != registeredCmps.second; iter++)
iter->second(someParam, someOtherParam);
}
break;
...
答案 0 :(得分:0)
我的第一个倾向,也许这里最简单的答案是为每种事件类型创建单独的数据结构。例如:
std::vector< EventDelegate< GUID, Point > > clickRegistry
std::vector< EventDelegate< char > > keyDownRegistry
用法
clickRegistry.push_back( EventDelegate(std::bind(&Foo::onLeftClick, myFoo, std::placeholders::_1, std::placeholders::_2)) );
虽然为什么在直接使用std::function
时在此处创建单独的委托尚不清楚。 (我可以看到将来在Delegate类中添加一堆其他实用程序,也许这就是你的意图。)
您希望通过包含所有已注册事件的单个数据结构实现什么目标?