#pragma once #include #include #include #include #include #include #include #include namespace Game::State { class GameState { public: static GameState& getInstance() { static GameState instance; return instance; } // Execute work while holding the GameState mutex to keep access thread-safe. template void withEntitiesLocked(Fn&& fn) { std::scoped_lock lock(mMutex); fn(mEntityMap); } void wipe(); Object::Entity* getEntityByName(const std::string& name); // Get an entity by name, returns nullptr if no entity with the name exists std::vector getEntitiesSnapshot(bool sortByZIndex = false); // Get a stable snapshot of entity pointers for iteration outside the lock void queueEntityRemoval(const std::string& name); void processPendingRemovals(); // Add an entity to the gamestate; returns a pointer to the stored entity. Object::Entity* addEntity(std::unique_ptr entity); bool removeEntity(const std::string& name); private: mutable std::mutex mMutex; // Shared mutex for thread safety std::unordered_map> mEntityMap; // Own entities while allowing O(1) lookup by name std::vector mPendingRemovals; }; }