08年05月20日

CEGUI的事件监听器又是如何实现的呢?
对于控件,每种控件有自己的事件,如:EventKeyUp等;每个事件后面可以挂着N个事件的回调方法;
event:function1,function2......
对控件订阅事件,如button->subscribeEvent(CEGUI::Windos::EventKeyUp,CEGUI:Event::Subscriber(&function,this));
把事件EventKeyUp注册到button中,并且在事件响应时回调函数fuction

内部实现机制是怎么样的呢?内部好像通过一个Map来查找到这个事件,但是又是如何响应到function的呢?哪位大哥指点下?

原来是一步步调用.我们设置一个断点在function,在DEBUG模式下"调用堆栈"
virtual bool operator()(const EventArgs& args)
    {
        return (d_object->*d_function)(args);
    }
再根据多态性
  bool operator()(const EventArgs& args) const
    {
        return (*d_functor_impl)(args);
    }
在事件类中
void Event::operator()(EventArgs& args)
{
    SlotContainer::iterator iter(d_slots.begin());
    const SlotContainer::const_iterator end_iter(d_slots.end());

    // execute all subscribers, updating the 'handled' state as we go
    for (; iter != end_iter; ++iter)
        args.handled |= (*iter->second->d_subscriber)(args);
}
事件设置:
void EventSet::fireEvent_impl(const String& name, EventArgs& args)
{
    // find event object
    Event* ev = getEventObject(name);

    // fire the event if present and set is not muted
    if ((ev != 0) && !d_muted)
        (*ev)(args);
}
void EventSet::fireEvent(const String& name, EventArgs& args, const String& eventNamespace)
{
    // handle global events
    GlobalEventSet::getSingleton().fireEvent(name, args, eventNamespace);
    // handle local event
    fireEvent_impl(name, args);
}
再到Window窗口中
void Window::onMouseClicked(MouseEventArgs& e)
{
    fireEvent(EventMouseClick, e, EventNamespace);
}
再到
bool System::injectMouseButtonUp(MouseButton button)
{
 ....
 while ((!ma.handled) && (dest_window != 0))
        {
            ma.window = dest_window;
            dest_window->onMouseClicked(ma);
            dest_window = getNextTargetWindow(dest_window);
        }
 ....
}
最后在Windows 消息处理中
LRESULT CALLBACK Win32AppHelper::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        .....
        case WM_LBUTTONUP:
        CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
        break;
        .....
    }

你可能感兴趣的:(08年05月20日)