// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequisites.hpp #pragma once #ifndef NDK_WORLD_HPP #define NDK_WORLD_HPP #include #include #include #include #include #include #include #include namespace Ndk { class World; using WorldHandle = Nz::ObjectHandle; class NDK_API World : public Nz::HandledObject { friend BaseSystem; friend Entity; public: using EntityVector = std::vector; struct ProfilerData; inline World(bool addDefaultSystems = true); World(const World&) = delete; inline World(World&& world) noexcept; ~World() noexcept; void AddDefaultSystems(); inline BaseSystem& AddSystem(std::unique_ptr&& system); template SystemType& AddSystem(Args&&... args); const EntityHandle& CreateEntity(); inline EntityVector CreateEntities(unsigned int count); void Clear() noexcept; const EntityHandle& CloneEntity(EntityId id); const EntityHandle& CloneEntity(const EntityHandle& entity); inline void DisableProfiler(); inline void EnableProfiler(bool enable = true); template void ForEachSystem(const F& iterationFunc); template void ForEachSystem(const F& iterationFunc) const; inline const EntityHandle& GetEntity(EntityId id); inline const EntityList& GetEntities() const; inline const ProfilerData& GetProfilerData() const; inline BaseSystem& GetSystem(SystemIndex index); inline const BaseSystem& GetSystem(SystemIndex index) const; template SystemType& GetSystem(); template const SystemType& GetSystem() const; inline bool HasSystem(SystemIndex index) const; template bool HasSystem() const; inline void KillEntity(Entity* entity); inline void KillEntities(const EntityVector& list); inline bool IsEntityDying(const Entity* entity) const; inline bool IsEntityDying(EntityId id) const; inline bool IsEntityValid(const Entity* entity) const; inline bool IsEntityIdValid(EntityId id) const; inline bool IsProfilerEnabled() const; void Refresh(); inline void RemoveAllSystems(); inline void RemoveSystem(SystemIndex index); template void RemoveSystem(); inline void ResetProfiler(); void Update(float elapsedTime); World& operator=(const World&) = delete; inline World& operator=(World&& world) noexcept; struct ProfilerData { Nz::UInt64 refreshTime = 0; std::vector updateTime; std::size_t updateCount = 0; }; private: inline void Invalidate(); inline void Invalidate(EntityId id); inline void InvalidateSystemOrder(); void ReorderSystems(); struct DoubleBitset { Nz::Bitset front; Nz::Bitset back; }; struct EntityBlock { EntityBlock(Entity&& e) : entity(std::move(e)), handle(&entity) { } EntityBlock(EntityBlock&& block) = default; Entity entity; EntityHandle handle; }; std::vector> m_systems; std::vector m_orderedSystems; std::vector m_entities; std::vector m_entityBlocks; std::vector> m_waitingEntities; EntityList m_aliveEntities; ProfilerData m_profilerData; DoubleBitset m_dirtyEntities; Nz::Bitset m_freeEntityIds; DoubleBitset m_killedEntities; bool m_orderedSystemsUpdated; bool m_isProfilerEnabled; }; } #include #endif // NDK_WORLD_HPP