【发布时间】:2021-11-26 22:32:42
【问题描述】:
我已经开始了我的游戏引擎之旅,我计划让它成为多线程的。考虑到这一点和堆分配成本,我编写了一个 EventPool 类,负责缓存事件分配,从而减少堆分配,但它增加了搜索先前分配的相同类型的“空闲”事件指针的额外成本。理想情况下,您只想进行堆栈分配,但考虑到每个 EventType 都需要向下转换,我不确定这是否可行。
每个事件触发并删除每个帧或保留 EventPool 并从中搜索是否更好?
事件触发:
template<typename EventType>
static void Publish(const EventType& e)
{
const auto& handlerIt = m_Subscribers.find(typeid(EventType));
if (handlerIt == m_Subscribers.end())
{
return;
}
auto ev = EventPool::Allocate<EventType>(e);
for (auto& handler : handlerIt->second)
{
if (!ev->IsHandled())
{
ev->m_Handled = handler(ev);
}
}
ev->m_Handled = true;
}
如果 EventPool 方法更好,我该如何优化它?
EventPool 分配器:
template<class EventType>
static EventType* Allocate(const EventType& e)
{
const auto& poolIt = m_EventPool.find(typeid(EventType));
EventType* newEvent;
if (poolIt == m_EventPool.end())
{
newEvent = new EventType;
memcpy(newEvent, &e, sizeof(EventType));
m_EventPool[typeid(EventType)].push_back(newEvent);
return newEvent;
}
else
{
for (Event* ev : poolIt->second)
{
if (ev->IsHandled())
{
newEvent = static_cast<EventType*>(ev);
memcpy(newEvent, &e, sizeof(EventType));
return newEvent;
}
}
newEvent = new EventType;
memcpy(newEvent, &e, sizeof(EventType));
poolIt->second.push_back(newEvent);
return newEvent;
}
}
【问题讨论】:
-
do heap allocation per event fire and delete per frame让我觉得你的所有事件都没有比游戏帧长(即使在游戏结束时未处理)。我说的对吗? -
是的,至少在单线程上不行。在多线程系统中,事件的句柄可能会延迟
-
我错过了这个“(即使在它结束时未处理)”。答案是否定的,在处理之前不会被删除。
标签: c++ events event-handling game-engine dynamic-memory-allocation