Posted on 2008-05-20 16:34
RichardHe 阅读(231)
评论(0) 编辑 收藏 引用
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;
.....
}