最近的编码中接触到了cegui,于是顺便看了一下它的事件机制,可以动态注册事件响应。
在高层次上,每一个窗口都是由EventSet派生而来,每当希望增加对一个Event的响应时,调用如下接口就可以动态的把一个
类的普通成员函数注册到一个事件map(以事件名称作为关键字)中:
Event::Connection subscribeEvent(const String& name, Event::Subscriber subscriber);
当窗口的对应事件发生时,程序会去map中查找到Subscriber然后调用其中保存的对象的成员函数。
在这之前我一直以为C++中只能做到通过类的继承注册派生类的普通成员函数(类似MFC中的做法),但是cegui中任何类的成员函数都可以注册。
cegui中是通过这几个类实现这样一种灵活的机制的:
SlotFunctorBase是一个普通的基类。
MemberFunctionSlot为一个包含有对象指针及成员函数指针的类模板。FreeFunctionSlot等则包含一个函数对象的类模板。它们两者皆从SlotFunctorBase派生而来。
SubscriberSlot是一个普通类,它保存一个SlotFunctorBase指针指向SlotFunctorBase的几个派生类模板的实例对象。
这样当调用subscribeEvent时,就会创建一个SubscriberSlot对象,指向某对象的成员函数,事件发生时查找map找到SubscriberSlot即可以通过它调用某对象的成员函数。
这其中容易出现的一个问题是,注册了某事件,但是对应的对象销毁了,于是map中保存的数据无效,当这个事件发生时通过map调用响应函数就会出现异常。
总的来说,cegui通过还不错的方式(比MFC好太多了)实现了C++中的委托吧,