Ich habe das mit std :: function und std :: bind gemacht.
Ich habe diese EventManager-Klasse geschrieben, die einen Vektor von Handlern in einer ungeordneten_Map speichert, die Ereignistypen (die nur const unsigned int sind, ich habe eine große Anzahl von Namespace-Bereichen) einem Vektor von Handlern für diesen Ereignistyp zuordnet.
In meiner EventManagerTests-Klasse habe ich einen Ereignishandler wie folgt eingerichtet:
auto delegate = std::bind(&EventManagerTests::OnKeyDown, this, std::placeholders::_1);
event_manager.AddEventListener(kEventKeyDown, delegate);
Hier ist die AddEventListener-Funktion:
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;
}
Hier ist die EventHandler-Typdefinition:
typedef std::function<void(Event *)> EventHandler;
Dann mache ich in EventManagerTests :: RaiseEvent Folgendes:
Engine::KeyDownEvent event(39);
event_manager.RaiseEvent(1, (Engine::Event*) & event);
Hier ist der Code für 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);
}
);
}
}
Das funktioniert. Ich erhalte den Aufruf in EventManagerTests :: OnKeyDown. Ich muss die Vektoren löschen, die Zeit zum Aufräumen haben, aber wenn ich das mache, gibt es keine Lecks. Das Auslösen eines Ereignisses dauert auf meinem Computer ungefähr 5 Mikrosekunden, was ungefähr 2008 entspricht. Nicht gerade superschnell, aber. Fair genug, solange ich das weiß und es nicht in extrem heißem Code verwende.
Ich möchte es beschleunigen, indem ich meine eigene std :: function und std :: bind rolle und vielleicht ein Array von Arrays anstelle einer ungeordneten Karte von Vektoren verwende, aber ich habe nicht ganz herausgefunden, wie eine Mitgliedsfunktion gespeichert werden soll Zeiger und rufen Sie es aus Code auf, der nichts über die aufgerufene Klasse weiß. Wimpern Antwort sieht sehr interessant aus ..