我的游戏引擎中有一个事件系统,由两个主要组件组成:Event 和 EventCallback。
事件.h:
#ifndef _EVENT_H_
#define _EVENT_H_
#include "EventCallback.h"
#include <vector>
template<typename... Args>
class Event
{
public:
Event() = default;
~Event()
{
for (IEventCallback<Args...>* action : m_actions)
delete action;
m_actions.clear();
}
void AddListener(IEventCallback<Args...>* action)
{
m_actions.push_back(action);
}
void RemoveListener(IEventCallback<Args...>* action)
{
auto position = std::find(m_actions.begin(), m_actions.end(), action);
if (position == m_actions.end())
return;
m_actions.erase(position);
if(action != nullptr)
delete action;
}
void Trigger(Args... args)
{
for (IEventCallback<Args...>* action : m_actions)
{
action->Trigger(args...);
}
}
private:
std::vector<IEventCallback<Args...>*> m_actions;
};
#endif
EventCallback.h:
#ifndef _EVENTCALLBACK_H_
#define _EVENTCALLBACK_H_
template<typename... Args>
class IEventCallback
{
public:
virtual bool operator == (IEventCallback* other) = 0;
virtual void Trigger(Args... args) = 0;
};
template<typename T, typename... Args>
class EventCallback : public IEventCallback<Args...>
{
public:
EventCallback(T* instance, void (T::* function)(Args... args))
{
m_instance = instance;
m_function = function;
}
virtual void Trigger(Args... args) override
{
if(m_instance != nullptr)
(m_instance->*m_function)(args...);
}
virtual bool operator == (IEventCallback<Args...>* other) override
{
EventCallback<T, Args...>* otherEventCallback = dynamic_cast<EventCallback<T, Args...>*>(other);
if (otherEventCallback == nullptr)
return false;
return (this->m_function == otherEventCallback->m_function) &&
(this->m_instance == otherEventCallback->m_instance);
}
private:
void (T::*m_function)(Args...);
T* m_instance;
};
#endif
目前,我可以创建一个事件并添加侦听器,如下所示:
CameraController* instance = new CameraController();
Event<InputCallbackData> Ongoing;
Ongoing.AddListener(new EventCallback<CameraController, InputCallbackData>(this, &CameraController::MoveRight));
void CameraController::MoveRight(InputCallbackData data)
{
Vector3D cameraPos = m_cameraComponent->GetWorldPosition();
Vector3D cameraRight = m_cameraComponent->GetWorldRotation().GetRightDirection();
m_cameraComponent->SetWorldPosition(cameraPos + cameraRight * movementSpeed);
}
InputCallbackData inputCallbackData = InputCallbackData();
Ongoing.Trigger(inputCallbackData);
现在,我想将参数预先绑定到EventCallback。这就是我的目标:
CameraController* instance = new CameraController();
Event<InputCallbackData> Ongoing;
Ongoing.AddListener(new EventCallback<CameraController, InputCallbackData>(this, &CameraController::MoveRight, 10));
void CameraController::MoveRight(InputCallbackData data, float speed)
{
Vector3D cameraPos = m_cameraComponent->GetWorldPosition();
Vector3D cameraRight = m_cameraComponent->GetWorldRotation().GetRightDirection();
m_cameraComponent->SetWorldPosition(cameraPos + cameraRight * speed);
}
InputCallbackData inputCallbackData = InputCallbackData();
Ongoing.Trigger(inputCallbackData);
我应该如何修改我的EventCallback类以支持预绑定参数?
我不知道如何实现我的目标:
CameraController* instance = new CameraController();
Event<InputCallbackData> Ongoing;
Ongoing.AddListener(new EventCallback<CameraController, InputCallbackData>(this, &CameraController::MoveRight, 10));
void CameraController::MoveRight(InputCallbackData data, float speed)
{
Vector3D cameraPos = m_cameraComponent->GetWorldPosition();
Vector3D cameraRight = m_cameraComponent->GetWorldRotation().GetRightDirection();
m_cameraComponent->SetWorldPosition(cameraPos + cameraRight * speed);
}
InputCallbackData inputCallbackData = InputCallbackData();
Ongoing.Trigger(inputCallbackData);
也许是这样的(未经测试):
template<typename T, typename... Args>
class EventCallback : public IEventCallback<Args...>
{
public:
template <typename... ExtraArgs
EventCallback(T* instance, void (T::* function)(Args..., ExtraArgs...),
const ExtraArgs&... extra_args) {
m_callback = [=](Args... args) {
(intance->*function)(args..., extra_args...);
};
}
virtual void Trigger(Args... args) override
{
if(m_callback)
m_callback(args...);
}
private:
std::function<void(Args...)> m_callback;
};