首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >事件系统优化

事件系统优化
EN

Stack Overflow用户
提问于 2012-05-22 18:07:20
回答 2查看 177关注 0票数 2

如果我有这些声明和定义:

代码语言:javascript
运行
复制
enum Events
{
  INIT,
  RENDER
};

struct EventBase
{
  typedef void (EventBase::*event_callback_type)();

  ~EventBase() {}

  virtual void init() { assert(0); }
  virtual void render() { assert(0); }
};

template <enum Events>
struct EventTraits
{
  static EventBase::event_callback_type const event_callback;
};

// in a .cpp file
template <>
EventBase::event_callback_type const
EventTraits<INIT>::event_callback(
  &EventBase::init);

template <>
EventBase::event_callback_type const
EventTraits<RENDER>::event_callback(
  &EventBase::render);

// in another class *i are pointers to objects that inherit EventBase
template <enum Events event>
inline void EventNotifier::notify()
{
  for (events_type::const_iterator i(event_handlers[event].begin());
    i != event_handlers[event].begin() + num_event_handlers[event];
    ++i)
  {
    ((*i)->*EventTraits<event>::event_callback)();

    if ((*i)->num_event_handlers[event])
    {
      (*i)->notify<event>();
    }
    // else do nothing
  }
}

比方说,事件渲染需要尽可能快的处理,你认为是否值得进行成员模板专门化:

代码语言:javascript
运行
复制
template <>
inline void EventNotifier::notify<RENDER>()
{
  for (events_type::const_iterator i(event_handlers[RENDER].begin());
    i != event_handlers[RENDER].begin() + num_event_handlers[RENDER];
    ++i)
  {
    (*i)->render();

    if ((*i)->num_event_handlers[RENDER])
    {
      (*i)->notify<RENDER>();
    }
    // else do nothing
  }
}

这将不需要获取指向成员函数的静态指针。或者我应该这样做:

代码语言:javascript
运行
复制
template <enum Events>
struct EventTraits
{
  static EventBase::event_callback_type event_callback();
};

并专门化结构模板?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-22 18:27:44

只需再加5美分。notify()看起来完全是线程不安全的。此外,如果任何事件处理程序生成新的事件,则可能会发生不好的事情。我建议这样做通知(C++ 11,只是不知道你的所有类型):

代码语言:javascript
运行
复制
template <> inline void EventNotifier::notify<RENDER>()
{
  decltype(event_handlers[RENDER]) local;
  decltype(num_event_handlers[RENDER]) local_num;

  {
    std::lock_guard<std::mutex> guard(my_mutex);
    local = event_handlers[RENDER];
    local_num = num_event_handlers[RENDER];
  }

  for (events_type::const_iterator i(local.begin()); i != local.begin() + local_num; ++i)
  {
    (*i)->render();

    if ((*i)->num_event_handlers[RENDER]) (*i)->notify<RENDER>();
  }
}
票数 2
EN

Stack Overflow用户

发布于 2012-05-22 18:51:18

成员专门化不会对其当前形式产生任何影响,因为您编写的代码与编译器将为您生成的代码完全相同。

这里有一个小的改进:

代码语言:javascript
运行
复制
template <enum Events event>
inline void EventNotifier::notify()
{
  for (events_type::const_iterator i(event_handlers[event].begin()),
       end (event_handlers[event].begin() + num_event_handlers[event]);
       i != end; ++i)
  {
    ((*i)->*EventTraits<event>::event_callback)();

    if ((*i)->num_event_handlers[event])
    {
      (*i)->notify<event>();
    }
    // else do nothing
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10699899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档