我正在计划一个事件驱动的游戏引擎。其基本思想是,不让所有的东西都与所有事物对话,而是与事件系统对话,事件系统将消息转发给他们的接收者,而不将接收者耦合到通知程序或相反的方式。
。
class Registration
{
public:
void callback(void){ callback_(); }
void setCallback((*callback)(void));
void addToEventSystem(int ID, EventSystem &eventSystem);
private:
void (*callback_)(void);
};
class EventSystem
{
public:
void register(int ID, Registration* registration);
void unRegister(int ID, Registration* registration);
void addNotificationToQueue(int ID);
void addNotificationToSchedule(int ID, int notificationTime);
void processQueuedNotifications(void);
void processNextScheduled(void);
int getCurrentTime(void);
private:
//placeholder types
<list> notificationQueue;
<binaryheap> notificationSchedule;
};
//------------Use:------------------
class ReceiverObject
{
public:
void doStuff(void);
void initialize(void){
keyPressRegistration.setCallback(doStuff);
//multiple registrations with different ID:s to same eventsystem possible
keyPressRegistration.addToEventSystem(1234,eventSystem);
keyPressRegistration.addToEventSystem(42,eventSystem);};
private:
Registration keyPressRegistration;
};
int main()
{
ReceiverObject receiverObject;
EventSystem eventSystem;
receiverObject.initialize();
eventSystem.addNotificationToQueue(1234);
eventSystem.processQueuedNotifications();
}然而,我对这个解决方案并不完全满意,主要是因为系统不允许将参数轻易传递给接收者,而且我对回调成员函数表示怀疑,这是否好的设计实践?我想出的方法/类/变量名呢?对这一问题的建设性批评、指导和替代办法是值得欢迎的。
发布于 2013-07-30 13:17:11
这与你的问题没有严格的关系,但是说到设计,我会避免使用全局通知系统,因为我在过去已经看到了不好的后果。您将倾向于在一个对象只对另一个对象调用某个方法的地方使用一个重事件系统。
专门化的模板化系统工作得更好,即允许您控制对象寿命的系统,以及设计用于处理特定类型事件和其中已知参数的系统。
无论如何,您都会发现很难解决问题,例如等待发送给已经死亡的收件人的未决事件。
发布于 2013-07-30 12:29:11
我个人会有一个EventHandler的接口类,您可以注册它,它将有一个虚拟的action函数(或者是事件系统告诉类它被取消注册的函数)。这完全避免了回调,EventHandler的实际实现将有可能保存其他数据(或对其他数据的引用)。
发布于 2013-07-30 14:14:45
对于参数问题,您可以定义基类ParamList,其派生项是模板化的:
class ParamList
{
const ID_Type& GetParamsType();
...
};
template <typename T>
class Params: public ParamList
{
...
}现在回调的类型是: void (*Callback)(ParamList&);为了安全使用,您可以添加到类Registration ID_Type& GetExpectedParamsType()中,并在调用回调之前使用它。
sames用于通知: void addNotificationToQueue(int ID,ParamList& param);void addNotificationToSchedule(int ID,ParamList& param,int notificationTime);
https://stackoverflow.com/questions/17946525
复制相似问题