SDK: Allow to set an update order for systems (Closes #106)
This commit is contained in:
parent
4570f9a6e1
commit
aa304ef2e9
|
|
@ -35,6 +35,7 @@ namespace Ndk
|
||||||
|
|
||||||
inline const std::vector<EntityHandle>& GetEntities() const;
|
inline const std::vector<EntityHandle>& GetEntities() const;
|
||||||
inline SystemIndex GetIndex() const;
|
inline SystemIndex GetIndex() const;
|
||||||
|
inline int GetUpdateOrder() const;
|
||||||
inline float GetUpdateRate() const;
|
inline float GetUpdateRate() const;
|
||||||
inline World& GetWorld() const;
|
inline World& GetWorld() const;
|
||||||
|
|
||||||
|
|
@ -42,6 +43,7 @@ namespace Ndk
|
||||||
|
|
||||||
inline bool HasEntity(const Entity* entity) const;
|
inline bool HasEntity(const Entity* entity) const;
|
||||||
|
|
||||||
|
void SetUpdateOrder(int updateOrder);
|
||||||
inline void SetUpdateRate(float updatePerSecond);
|
inline void SetUpdateRate(float updatePerSecond);
|
||||||
|
|
||||||
inline void Update(float elapsedTime);
|
inline void Update(float elapsedTime);
|
||||||
|
|
@ -93,6 +95,7 @@ namespace Ndk
|
||||||
bool m_updateEnabled;
|
bool m_updateEnabled;
|
||||||
float m_updateCounter;
|
float m_updateCounter;
|
||||||
float m_updateRate;
|
float m_updateRate;
|
||||||
|
int m_updateOrder;
|
||||||
|
|
||||||
static SystemIndex s_nextIndex;
|
static SystemIndex s_nextIndex;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,9 @@ namespace Ndk
|
||||||
|
|
||||||
inline BaseSystem::BaseSystem(SystemIndex systemId) :
|
inline BaseSystem::BaseSystem(SystemIndex systemId) :
|
||||||
m_systemIndex(systemId),
|
m_systemIndex(systemId),
|
||||||
m_updateEnabled(true)
|
m_world(nullptr),
|
||||||
|
m_updateEnabled(true),
|
||||||
|
m_updateOrder(0)
|
||||||
{
|
{
|
||||||
SetUpdateRate(30);
|
SetUpdateRate(30);
|
||||||
}
|
}
|
||||||
|
|
@ -33,7 +35,8 @@ namespace Ndk
|
||||||
m_systemIndex(system.m_systemIndex),
|
m_systemIndex(system.m_systemIndex),
|
||||||
m_updateEnabled(system.m_updateEnabled),
|
m_updateEnabled(system.m_updateEnabled),
|
||||||
m_updateCounter(0.f),
|
m_updateCounter(0.f),
|
||||||
m_updateRate(system.m_updateRate)
|
m_updateRate(system.m_updateRate),
|
||||||
|
m_updateOrder(system.m_updateOrder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +72,18 @@ namespace Ndk
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the rate of update for the system
|
* \brief Gets the update order of the system
|
||||||
|
* \return Update order
|
||||||
|
*
|
||||||
|
* \see SetUpdateOrder
|
||||||
|
*/
|
||||||
|
inline int BaseSystem::GetUpdateOrder() const
|
||||||
|
{
|
||||||
|
return m_updateOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the rate of update of the system
|
||||||
* \return Update rate
|
* \return Update rate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace Ndk
|
||||||
|
|
||||||
class NDK_API World : public Nz::HandledObject<World>
|
class NDK_API World : public Nz::HandledObject<World>
|
||||||
{
|
{
|
||||||
|
friend BaseSystem;
|
||||||
friend Entity;
|
friend Entity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -72,6 +73,8 @@ namespace Ndk
|
||||||
private:
|
private:
|
||||||
inline void Invalidate();
|
inline void Invalidate();
|
||||||
inline void Invalidate(EntityId id);
|
inline void Invalidate(EntityId id);
|
||||||
|
inline void InvalidateSystemOrder();
|
||||||
|
void ReorderSystems();
|
||||||
|
|
||||||
struct EntityBlock
|
struct EntityBlock
|
||||||
{
|
{
|
||||||
|
|
@ -87,11 +90,13 @@ namespace Ndk
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::unique_ptr<BaseSystem>> m_systems;
|
std::vector<std::unique_ptr<BaseSystem>> m_systems;
|
||||||
|
std::vector<BaseSystem*> m_orderedSystems;
|
||||||
std::vector<EntityBlock> m_entities;
|
std::vector<EntityBlock> m_entities;
|
||||||
std::vector<EntityId> m_freeIdList;
|
std::vector<EntityId> m_freeIdList;
|
||||||
EntityList m_aliveEntities;
|
EntityList m_aliveEntities;
|
||||||
Nz::Bitset<Nz::UInt64> m_dirtyEntities;
|
Nz::Bitset<Nz::UInt64> m_dirtyEntities;
|
||||||
Nz::Bitset<Nz::UInt64> m_killedEntities;
|
Nz::Bitset<Nz::UInt64> m_killedEntities;
|
||||||
|
bool m_orderedSystemsUpdated;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ namespace Ndk
|
||||||
m_systems[index]->SetWorld(this);
|
m_systems[index]->SetWorld(this);
|
||||||
|
|
||||||
Invalidate(); // We force an update for every entities
|
Invalidate(); // We force an update for every entities
|
||||||
|
InvalidateSystemOrder(); // And regenerate the system update list
|
||||||
|
|
||||||
return *m_systems[index].get();
|
return *m_systems[index].get();
|
||||||
}
|
}
|
||||||
|
|
@ -206,6 +207,8 @@ namespace Ndk
|
||||||
inline void World::RemoveAllSystems()
|
inline void World::RemoveAllSystems()
|
||||||
{
|
{
|
||||||
m_systems.clear();
|
m_systems.clear();
|
||||||
|
|
||||||
|
InvalidateSystemOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -219,7 +222,11 @@ namespace Ndk
|
||||||
inline void World::RemoveSystem(SystemIndex index)
|
inline void World::RemoveSystem(SystemIndex index)
|
||||||
{
|
{
|
||||||
if (HasSystem(index))
|
if (HasSystem(index))
|
||||||
|
{
|
||||||
m_systems[index].reset();
|
m_systems[index].reset();
|
||||||
|
|
||||||
|
InvalidateSystemOrder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -246,32 +253,11 @@ namespace Ndk
|
||||||
Update(); //< Update entities
|
Update(); //< Update entities
|
||||||
|
|
||||||
// And then update systems
|
// And then update systems
|
||||||
for (auto& systemPtr : m_systems)
|
if (!m_orderedSystemsUpdated)
|
||||||
{
|
ReorderSystems();
|
||||||
if (systemPtr)
|
|
||||||
systemPtr->Update(elapsedTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
for (auto& systemPtr : m_orderedSystems)
|
||||||
* \brief Invalidates each entity in the world
|
systemPtr->Update(elapsedTime);
|
||||||
*/
|
|
||||||
|
|
||||||
inline void World::Invalidate()
|
|
||||||
{
|
|
||||||
m_dirtyEntities.Resize(m_entities.size(), false);
|
|
||||||
m_dirtyEntities.Set(true); // Activation of all bits
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Invalidates an entity in the world
|
|
||||||
*
|
|
||||||
* \param id Identifier of the entity
|
|
||||||
*/
|
|
||||||
|
|
||||||
inline void World::Invalidate(EntityId id)
|
|
||||||
{
|
|
||||||
m_dirtyEntities.UnboundedSet(id, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -281,10 +267,12 @@ namespace Ndk
|
||||||
|
|
||||||
inline World& World::operator=(World&& world) noexcept
|
inline World& World::operator=(World&& world) noexcept
|
||||||
{
|
{
|
||||||
m_aliveEntities = std::move(world.m_aliveEntities);
|
m_aliveEntities = std::move(world.m_aliveEntities);
|
||||||
m_dirtyEntities = std::move(world.m_dirtyEntities);
|
m_dirtyEntities = std::move(world.m_dirtyEntities);
|
||||||
m_freeIdList = std::move(world.m_freeIdList);
|
m_freeIdList = std::move(world.m_freeIdList);
|
||||||
m_killedEntities = std::move(world.m_killedEntities);
|
m_killedEntities = std::move(world.m_killedEntities);
|
||||||
|
m_orderedSystems = std::move(world.m_orderedSystems);
|
||||||
|
m_orderedSystemsUpdated = world.m_orderedSystemsUpdated;
|
||||||
|
|
||||||
m_entities = std::move(world.m_entities);
|
m_entities = std::move(world.m_entities);
|
||||||
for (EntityBlock& block : m_entities)
|
for (EntityBlock& block : m_entities)
|
||||||
|
|
@ -296,4 +284,20 @@ namespace Ndk
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void World::Invalidate()
|
||||||
|
{
|
||||||
|
m_dirtyEntities.Resize(m_entities.size(), false);
|
||||||
|
m_dirtyEntities.Set(true); // Activation of all bits
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void World::Invalidate(EntityId id)
|
||||||
|
{
|
||||||
|
m_dirtyEntities.UnboundedSet(id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void World::InvalidateSystemOrder()
|
||||||
|
{
|
||||||
|
m_orderedSystemsUpdated = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
||||||
|
|
||||||
#include <NDK/BaseSystem.hpp>
|
#include <NDK/BaseSystem.hpp>
|
||||||
|
#include <NDK/World.hpp>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
|
|
@ -56,6 +57,26 @@ namespace Ndk
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the update order of this system
|
||||||
|
*
|
||||||
|
* The system update order is used by the world it belongs to in order to know in which order they should be updated, as some application logic may rely a specific update order.
|
||||||
|
* A system with a greater update order (ex: 1) is guaranteed to be updated after a system with a lesser update order (ex: -1), otherwise the order is unspecified (and is not guaranteed to be stable).
|
||||||
|
*
|
||||||
|
* \param updateOrder The relative update order of the system
|
||||||
|
*
|
||||||
|
* \remark The update order is only used by World::Update(float) and does not have any effect regarding a call to BaseSystem::Update(float)
|
||||||
|
*
|
||||||
|
* \see GetUpdateOrder
|
||||||
|
*/
|
||||||
|
inline void BaseSystem::SetUpdateOrder(int updateOrder)
|
||||||
|
{
|
||||||
|
m_updateOrder = updateOrder;
|
||||||
|
|
||||||
|
if (m_world)
|
||||||
|
m_world->InvalidateSystemOrder();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operation to perform when entity is added to the system
|
* \brief Operation to perform when entity is added to the system
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -249,4 +249,22 @@ namespace Ndk
|
||||||
}
|
}
|
||||||
m_dirtyEntities.Reset();
|
m_dirtyEntities.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::ReorderSystems()
|
||||||
|
{
|
||||||
|
m_orderedSystems.clear();
|
||||||
|
|
||||||
|
for (auto& systemPtr : m_systems)
|
||||||
|
{
|
||||||
|
if (systemPtr)
|
||||||
|
m_orderedSystems.push_back(systemPtr.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(m_orderedSystems.begin(), m_orderedSystems.end(), [] (BaseSystem* first, BaseSystem* second)
|
||||||
|
{
|
||||||
|
return first->GetUpdateOrder() < second->GetUpdateOrder();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_orderedSystemsUpdated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue