From 8d73b907ee4310b9372e8bc353ffcee24df00846 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Wed, 5 Mar 2014 19:04:40 +1100 Subject: Use vector rather than unordered_map for event dispatching. --- entityx/Benchmarks_test.cc | 33 +++++++++++++++++++++------------ entityx/Event.cc | 3 ++- entityx/Event.h | 22 ++++++++++------------ entityx/Event_test.cc | 8 ++++---- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/entityx/Benchmarks_test.cc b/entityx/Benchmarks_test.cc index cf431ab..c3e0ed3 100644 --- a/entityx/Benchmarks_test.cc +++ b/entityx/Benchmarks_test.cc @@ -20,8 +20,11 @@ private: }; struct Listener : public Receiver { - void receive(const EntityCreatedEvent &event) {} - void receive(const EntityDestroyedEvent &event) {} + void receive(const EntityCreatedEvent &event) { ++created; } + void receive(const EntityDestroyedEvent &event) { ++destroyed; } + + int created = 0; + int destroyed = 0; }; struct Position : public Component { @@ -67,39 +70,45 @@ TEST_CASE_METHOD(BenchmarkFixture, "TestCreateEntitiesWithListener") { Listener listen; ev.subscribe(listen); - uint64_t count = 10000000L; + int count = 10000000L; AutoTimer t; cout << "creating " << count << " entities while notifying a single EntityCreatedEvent listener" << endl; vector entities; - for (uint64_t i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { entities.push_back(em.create()); } + + REQUIRE(entities.size() == count); + REQUIRE(listen.created == count); } TEST_CASE_METHOD(BenchmarkFixture, "TestDestroyEntitiesWithListener") { - Listener listen; - ev.subscribe(listen); - - uint64_t count = 10000000L; + int count = 10000000; vector entities; - for (uint64_t i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { entities.push_back(em.create()); } + Listener listen; + ev.subscribe(listen); + AutoTimer t; - cout << "destroying " << count << " entities" << endl; + cout << "destroying " << count << " entities while notifying a single EntityDestroyedEvent listener" << endl; for (auto &e : entities) { e.destroy(); } + + REQUIRE(entities.size() == count); + REQUIRE(listen.destroyed == count); } TEST_CASE_METHOD(BenchmarkFixture, "TestEntityIteration") { - uint64_t count = 10000000L; + int count = 10000000; vector entities; - for (uint64_t i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { auto e = em.create(); e.assign(); entities.push_back(e); diff --git a/entityx/Event.cc b/entityx/Event.cc index db73d79..36896a0 100644 --- a/entityx/Event.cc +++ b/entityx/Event.cc @@ -12,7 +12,8 @@ namespace entityx { -BaseEvent::Family BaseEvent::family_counter_ = 1; +BaseEvent::Family BaseEvent::family_counter_ = 0; + EventManager::EventManager() { } diff --git a/entityx/Event.h b/entityx/Event.h index d2a2bb2..e7d7def 100644 --- a/entityx/Event.h +++ b/entityx/Event.h @@ -10,8 +10,8 @@ #pragma once -#include #include +#include #include #include #include @@ -166,21 +166,19 @@ class EventManager : entityx::help::NonCopyable { int connected_receivers() const { int size = 0; - for (auto pair : handlers_) { - size += pair.second->size(); + for (EventSignalPtr handler : handlers_) { + if (handler) size += handler->size(); } return size; } private: - EventSignalPtr signal_for(int id) { - auto it = handlers_.find(id); - if (it == handlers_.end()) { - EventSignalPtr sig(new EventSignal()); - handlers_.insert(std::make_pair(id, sig)); - return sig; - } - return it->second; + EventSignalPtr &signal_for(size_t id) { + if (id >= handlers_.size()) + handlers_.resize(id + 1); + if (!handlers_[id]) + handlers_[id] = std::make_shared(); + return handlers_[id]; } // Functor used as an event signal callback that casts to E. @@ -191,7 +189,7 @@ class EventManager : entityx::help::NonCopyable { std::function callback; }; - std::unordered_map handlers_; + std::vector handlers_; }; } // namespace entityx diff --git a/entityx/Event_test.cc b/entityx/Event_test.cc index 92a5547..04d0640 100644 --- a/entityx/Event_test.cc +++ b/entityx/Event_test.cc @@ -34,7 +34,7 @@ struct ExplosionSystem : public Receiver { int damage_received = 0; }; -TEST_CASE("TestEmitReceive", "[eventmanager]") { +TEST_CASE("TestEmitReceive") { EventManager em; ExplosionSystem explosion_system; em.subscribe(explosion_system); @@ -43,7 +43,7 @@ TEST_CASE("TestEmitReceive", "[eventmanager]") { REQUIRE(10 == explosion_system.damage_received); } -TEST_CASE("TestUntypedEmitReceive", "[eventmanager]") { +TEST_CASE("TestUntypedEmitReceive") { EventManager em; ExplosionSystem explosion_system; em.subscribe(explosion_system); @@ -54,7 +54,7 @@ TEST_CASE("TestUntypedEmitReceive", "[eventmanager]") { } -TEST_CASE("TestReceiverExpired", "[eventmanager]") { +TEST_CASE("TestReceiverExpired") { EventManager em; { ExplosionSystem explosion_system; @@ -68,7 +68,7 @@ TEST_CASE("TestReceiverExpired", "[eventmanager]") { } -TEST_CASE("TestSenderExpired", "[eventmanager]") { +TEST_CASE("TestSenderExpired") { ExplosionSystem explosion_system; { EventManager em; -- cgit v1.2.3