C++:游戏引擎的事件系统实现

jms*_*jms 2 c++ events game-engine

我正在计划一个事件驱动的游戏引擎.基本的想法是,不是让所有事情都与所有事情交谈,一切都会与事件系统进行对话,事件系统会将消息转发给收件人,而不会将收件人与通知者联系起来,反之亦然.

  • 对象将自己注册到事件系统.通知ID和指向回调函数的指针作为每个注册命令的参数传递.
  • 对象向事件系统添加通知.通知的ID作为每个通知的参数传递.通知将添加到包含所有待处理通知的队列中.
  • 此外,事件系统支持预定通知.通知ID和将来的执行时间作为每个通知的参数传递.然后将计划的通知存储在按照未来执行时间的顺序保存计划通知的数据结构("计划")中.
  • 调用者对象命令事件系统处理所有排队的通知.事件系统按顺序提取通知,并调用已使用与当前通知相同的ID注册自身的每个对象的回调函数.
  • 调用者对象命令事件系统处理一个预定的通知.从调度中获取最旧的通知,并调用使用相同通知ID注册的所有对象的回调.

.

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();
}
Run Code Online (Sandbox Code Playgroud)

但是我对这个解决方案并不完全满意,主要是因为系统不允许将参数轻松传递给收件人,而且我对成员函数的回调持怀疑态度,这是一个很好的设计实践吗?我想出的方法/类/变量名称怎么样?对这个问题的建设性批评,指导和替代方法是值得欢迎的.

Kar*_*dur 5

它与你的问题没有严格的关系,但谈到设计,我会避免使用全球通知系统"为所有事情",因为我看到过去的不良后果.你只是倾向于在一个对象只能在另一个对象上调用某个方法的地方使用繁重的事件系统.

专业的模板化系统工作得更好,即允许您控制对象寿命的系统,以及用于处理特定类型事件和其中已知参数的系统.

在任何情况下,你都会发现很难解决诸如等待交付给已经被杀死的收件人的待处理事件之类的问题.