And yet another enable_shared_from_this question: Basically, I got three things.
- System classes that contain application logic and might or might not be event listeners.
- Some kind of EventManager, that maps events to shared_ptrs of interested systems.
- Some kind of SystemManager, that holds a std::list of shared_ptrs to System objects.
Now, each system should be able to register itself with the EventManager for all kinds of events it is interested in. Moreover, they should be able to de-register themselves for these events if they aren't interested in them any more.
However, I'm not sure how to create systems in the system manager and sign them up in a way that avoids two ownership groups.
From the SystemManager:
void SystemManager::AddSystem(GameSystem* system)
{
// Take ownership of the specified system.
systems.push_back(std::shared_ptr<GameSystem>(system));
}
From the EventManager:
typedef std::shared_ptr<IEventListener> EventListenerPtr;
void EventManager::AddListener(EventListenerPtr const & listener, HashedString const & eventType)
{
// Get the event type entry in the listeners map.
std::map<unsigned long, std::list<EventListenerPtr>>::iterator iterator = this->listeners.find(eventType.getHash());
if (iterator != this->listeners.end())
{
std::list<EventListenerPtr> & eventListeners = iterator->second;
// Add listener.
eventListeners.push_back(listener);
}
else
{
// Add new entry to listeners map, removed for sake of simplicity of this example.
}
}
From some arbitrary system that wants to receive events:
void RenderSystem::InitSystem(std::shared_ptr<GameInfrastructure> game)
{
// BAD: Creates second ownership group.
this->game->eventManager->AddListener(std::shared_ptr<IEventListener>(this), AppWindowChangedEvent::AppWindowChangedEventType);
}
I have read my references recommending enable_shared_from_this. However, as the systems don't own themselves, they don't have access to the shared_ptr held by the SystemManager who originally created the systems and took ownership of them.
Any ideas of an elegant way to solve this?