Saya melakukan ini dengan std :: function dan std :: bind ..
Saya menulis kelas EventManager ini yang menyimpan vektor penangan dalam unordered_map yang memetakan jenis peristiwa (yang hanya const unsigned int, saya memiliki enum lingkup namespace besar dari mereka) ke vektor penangan untuk jenis peristiwa itu.
Di kelas EventManagerTests saya, saya menyiapkan penangan peristiwa, seperti ini:
auto delegate = std::bind(&EventManagerTests::OnKeyDown, this, std::placeholders::_1);
event_manager.AddEventListener(kEventKeyDown, delegate);
Inilah fungsi 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;
}
Berikut definisi tipe EventHandler:
typedef std::function<void(Event *)> EventHandler;
Kemudian kembali ke EventManagerTests :: RaiseEvent, saya melakukan ini:
Engine::KeyDownEvent event(39);
event_manager.RaiseEvent(1, (Engine::Event*) & event);
Berikut kode untuk 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);
}
);
}
}
Ini bekerja. Saya mendapatkan panggilan di EventManagerTests :: OnKeyDown. Saya harus menghapus vektor datang waktu pembersihan, tetapi begitu saya melakukannya, tidak ada kebocoran. Meningkatkan acara membutuhkan waktu sekitar 5 mikrodetik di komputer saya, yaitu sekitar tahun 2008. Tidak bisa dibilang super cepat, tapi. Cukup adil selama saya mengetahuinya dan saya tidak menggunakannya dalam kode ultra hot.
Saya ingin mempercepatnya dengan menggulung std :: function dan std :: bind saya sendiri, dan mungkin menggunakan array array daripada unordered_map vektor, tetapi saya belum cukup menemukan cara menyimpan fungsi anggota pointer dan memanggilnya dari kode yang tidak tahu apa-apa tentang kelas yang dipanggil. Jawaban bulu mata terlihat Sangat Menarik ..