Bunu std :: function ve std :: bind .. ile yaptım.
Bu EventManager sınıfını, olay türlerini (bunlar sadece const unsigned int, büyük bir ad alanı kapsamlı enumum var) bu olay türü için bir işleyici vektörüne eşleyen bir unordered_map içinde depolayan bu EventManager sınıfını yazdım.
EventManagerTests sınıfımda, şunun gibi bir olay işleyicisi ayarlıyorum:
auto delegate = std::bind(&EventManagerTests::OnKeyDown, this, std::placeholders::_1);
event_manager.AddEventListener(kEventKeyDown, delegate);
AddEventListener işlevi şöyledir:
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 türü tanımı şöyledir:
typedef std::function<void(Event *)> EventHandler;
Sonra EventManagerTests :: RaiseEvent'e geri dönün, şunu yapıyorum:
Engine::KeyDownEvent event(39);
event_manager.RaiseEvent(1, (Engine::Event*) & event);
EventManager :: RaiseEvent kodu şöyledir:
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);
}
);
}
}
Bu çalışıyor. Çağrıyı EventManagerTests :: OnKeyDown'da alıyorum. Temizleme zamanı gelen vektörleri silmem gerekiyor, ancak bunu yaptıktan sonra herhangi bir sızıntı yok. Bir olayı oluşturmak, bilgisayarımda yaklaşık 5 mikrosaniye sürüyor, bu yaklaşık 2008. Tam olarak süper hızlı değil, ama. Bunu bildiğim sürece yeterince adil ve onu ultra sıcak kodda kullanmıyorum.
Kendi std :: fonksiyonumu ve std :: bind'imi yuvarlayarak ve belki de sırasız bir vektör haritası yerine bir dizi dizisi kullanarak bunu hızlandırmak istiyorum, ancak bir üye fonksiyonunu nasıl saklayacağımı tam olarak çözemedim pointer ve çağrılan sınıf hakkında hiçbir şey bilmeyen koddan çağırın. Kirpik'in cevabı Çok İlginç görünüyor ..