std :: function 및 std :: bind ..
나는 이벤트 유형 (그냥 const unsigned int, 큰 네임 스페이스 범위 열거 형)을 해당 이벤트 유형에 대한 핸들러 벡터에 매핑하는 unorder_map에 핸들러 벡터를 저장하는이 EventManager 클래스를 작성했습니다.
EventManagerTests 클래스에서 다음과 같이 이벤트 핸들러를 설정했습니다.
auto delegate = std::bind(&EventManagerTests::OnKeyDown, this, std::placeholders::_1);
event_manager.AddEventListener(kEventKeyDown, delegate);
다음은 AddEventListener 함수입니다.
std::vector<EventHandler>::iterator EventManager::AddEventListener(EventType _event_type, EventHandler _handler)
{
if (listeners_.count(_event_type) == 0)
{
listeners_.emplace(_event_type, new std::vector<EventHandler>());
}
std::vector<EventHandler>::iterator it = listeners_[_event_type]->end();
listeners_[_event_type]->push_back(_handler);
return it;
}
다음은 EventHandler 유형 정의입니다.
typedef std::function<void(Event *)> EventHandler;
그런 다음 EventManagerTests :: RaiseEvent로 돌아가서 다음을 수행합니다.
Engine::KeyDownEvent event(39);
event_manager.RaiseEvent(1, (Engine::Event*) & event);
EventManager :: RaiseEvent에 대한 코드는 다음과 같습니다.
void EventManager::RaiseEvent(EventType _event_type, Event * _event)
{
if (listeners_.count(_event_type) > 0)
{
std::vector<EventHandler> * vec = listeners_[_event_type];
std::for_each(
begin(*vec),
end(*vec),
[_event](EventHandler handler) mutable
{
(handler)(_event);
}
);
}
}
작동합니다. EventManagerTests :: OnKeyDown에서 호출을받습니다. 벡터를 삭제해야 정리 시간이 오지만 일단 삭제하면 누수가 없습니다. 이벤트를 발생시키는 데는 내 컴퓨터에서 약 5 마이크로 초가 소요됩니다. 이는 2008 년경입니다. 정확히 초고속은 아니지만. 내가 그것을 알고 있고 울트라 핫 코드에서 사용하지 않는 한 충분히 공정합니다.
내 자신의 std :: function 및 std :: bind를 굴려서 속도를 높이고 싶고 정렬되지 않은 벡터 맵 대신 배열 배열을 사용하고 싶지만 멤버 함수를 저장하는 방법을 알지 못했습니다. 포인터를 호출하고 호출되는 클래스에 대해 아무것도 모르는 코드에서 호출합니다. 속눈썹의 대답은 매우 흥미로워 보입니다 ..