Merge branch 'entitylist-refactor' of https://github.com/DigitalPulseSoftware/NazaraEngine into entitylist-refactor
This commit is contained in:
commit
1b66948213
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <Nazara/Core/Bitset.hpp>
|
||||
#include <NDK/Entity.hpp>
|
||||
#include <NDK/EntityList.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Ndk
|
||||
|
|
@ -33,7 +34,7 @@ namespace Ndk
|
|||
|
||||
bool Filters(const Entity* entity) const;
|
||||
|
||||
inline const std::vector<EntityHandle>& GetEntities() const;
|
||||
inline const EntityList& GetEntities() const;
|
||||
inline SystemIndex GetIndex() const;
|
||||
inline int GetUpdateOrder() const;
|
||||
inline float GetUpdateRate() const;
|
||||
|
|
@ -84,12 +85,11 @@ namespace Ndk
|
|||
static inline bool Initialize();
|
||||
static inline void Uninitialize();
|
||||
|
||||
std::vector<EntityHandle> m_entities;
|
||||
Nz::Bitset<Nz::UInt64> m_entityBits;
|
||||
Nz::Bitset<> m_excludedComponents;
|
||||
mutable Nz::Bitset<> m_filterResult;
|
||||
Nz::Bitset<> m_requiredAnyComponents;
|
||||
Nz::Bitset<> m_requiredComponents;
|
||||
EntityList m_entities;
|
||||
SystemIndex m_systemIndex;
|
||||
World* m_world;
|
||||
bool m_updateEnabled;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace Ndk
|
|||
* \return A constant reference to the list of entities
|
||||
*/
|
||||
|
||||
inline const std::vector<EntityHandle>& BaseSystem::GetEntities() const
|
||||
inline const EntityList& BaseSystem::GetEntities() const
|
||||
{
|
||||
return m_entities;
|
||||
}
|
||||
|
|
@ -121,10 +121,7 @@ namespace Ndk
|
|||
|
||||
inline bool BaseSystem::HasEntity(const Entity* entity) const
|
||||
{
|
||||
if (!entity)
|
||||
return false;
|
||||
|
||||
return m_entityBits.UnboundedTest(entity->GetId());
|
||||
return m_entities.Has(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -288,9 +285,7 @@ namespace Ndk
|
|||
{
|
||||
NazaraAssert(entity, "Invalid entity");
|
||||
|
||||
m_entities.emplace_back(entity);
|
||||
m_entityBits.UnboundedSet(entity->GetId(), true);
|
||||
|
||||
m_entities.Insert(entity);
|
||||
entity->RegisterSystem(m_systemIndex);
|
||||
|
||||
OnEntityAdded(entity);
|
||||
|
|
@ -308,14 +303,7 @@ namespace Ndk
|
|||
{
|
||||
NazaraAssert(entity, "Invalid entity");
|
||||
|
||||
auto it = std::find(m_entities.begin(), m_entities.end(), *entity);
|
||||
NazaraAssert(it != m_entities.end(), "Entity is not part of this system");
|
||||
|
||||
// To avoid moving a lot of handles, we swap and pop
|
||||
std::swap(*it, m_entities.back());
|
||||
m_entities.pop_back(); // We get it out of the vector
|
||||
|
||||
m_entityBits.Reset(entity->GetId());
|
||||
m_entities.Remove(entity);
|
||||
entity->UnregisterSystem(m_systemIndex);
|
||||
|
||||
OnEntityRemoved(entity); // And we alert our callback
|
||||
|
|
@ -360,7 +348,7 @@ namespace Ndk
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Uninitializes the BaseSystem
|
||||
* \brief Uninitialize the BaseSystem
|
||||
*/
|
||||
|
||||
inline void BaseSystem::Uninitialize()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace Ndk
|
|||
using size_type = std::size_t;
|
||||
|
||||
inline EntityList();
|
||||
inline EntityList(const EntityList& entityList);
|
||||
inline EntityList(EntityList&& entityList) noexcept;
|
||||
~EntityList() = default;
|
||||
|
||||
inline void Clear();
|
||||
|
|
@ -33,11 +35,14 @@ namespace Ndk
|
|||
inline void Remove(Entity* entity);
|
||||
|
||||
// STL API
|
||||
inline iterator begin();
|
||||
inline iterator begin() const;
|
||||
inline bool empty() const;
|
||||
inline iterator end();
|
||||
inline iterator end() const;
|
||||
inline size_type size() const;
|
||||
|
||||
inline EntityList& operator=(const EntityList& entityList);
|
||||
inline EntityList& operator=(EntityList&& entityList) noexcept;
|
||||
|
||||
private:
|
||||
inline std::size_t FindNext(std::size_t currentId) const;
|
||||
inline World* GetWorld() const;
|
||||
|
|
@ -46,7 +51,7 @@ namespace Ndk
|
|||
World* m_world;
|
||||
};
|
||||
|
||||
class EntityList::iterator : public std::iterator<std::forward_iterator_tag, const EntityHandle>
|
||||
class NDK_API EntityList::iterator : public std::iterator<std::forward_iterator_tag, const EntityHandle>
|
||||
{
|
||||
friend EntityList;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,32 @@ namespace Ndk
|
|||
*/
|
||||
|
||||
/*!
|
||||
* \brief Clears the set from every entities
|
||||
* \brief Construct a new entity list
|
||||
*/
|
||||
inline EntityList::EntityList() :
|
||||
m_world(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new entity list by copying another one
|
||||
*/
|
||||
inline EntityList::EntityList(const EntityList& entityList) :
|
||||
m_entityBits(entityList.m_entityBits),
|
||||
m_world(entityList.m_world)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Construct a new entity list by moving a list into this one
|
||||
*/
|
||||
inline EntityList::EntityList(EntityList&& entityList) noexcept :
|
||||
m_entityBits(std::move(entityList.m_entityBits)),
|
||||
m_world(entityList.m_world)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Clears the set from every entities
|
||||
*
|
||||
|
|
@ -96,17 +115,17 @@ namespace Ndk
|
|||
}
|
||||
|
||||
// STL Interface
|
||||
inline EntityList::iterator EntityList::begin()
|
||||
inline EntityList::iterator EntityList::begin() const
|
||||
{
|
||||
return EntityList::iterator(this, m_entityBits.FindFirst());
|
||||
}
|
||||
|
||||
inline bool EntityList::empty() const
|
||||
{
|
||||
return m_entityBits.TestAny();
|
||||
return !m_entityBits.TestAny();
|
||||
}
|
||||
|
||||
inline EntityList::iterator EntityList::end()
|
||||
inline EntityList::iterator EntityList::end() const
|
||||
{
|
||||
return EntityList::iterator(this, m_entityBits.npos);
|
||||
}
|
||||
|
|
@ -116,6 +135,22 @@ namespace Ndk
|
|||
return m_entityBits.Count();
|
||||
}
|
||||
|
||||
inline EntityList& EntityList::operator=(const EntityList& entityList)
|
||||
{
|
||||
m_entityBits = entityList.m_entityBits;
|
||||
m_world = entityList.m_world;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline EntityList& EntityList::operator=(EntityList && entityList) noexcept
|
||||
{
|
||||
m_entityBits = std::move(entityList.m_entityBits);
|
||||
m_world = entityList.m_world;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline std::size_t EntityList::FindNext(std::size_t currentId) const
|
||||
{
|
||||
return m_entityBits.FindNext(currentId);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// 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 Prerequesites.hpp
|
||||
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
#include <NDK/Prerequesites.hpp>
|
||||
#include <NDK/State.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Ndk
|
||||
{
|
||||
|
|
@ -25,14 +26,21 @@ namespace Ndk
|
|||
|
||||
inline const std::shared_ptr<State>& GetCurrentState() const;
|
||||
|
||||
inline bool IsTopState(const State* state) const;
|
||||
|
||||
inline std::shared_ptr<State> PopState();
|
||||
inline bool PopStatesUntil(std::shared_ptr<State> state);
|
||||
inline void PushState(std::shared_ptr<State> state);
|
||||
|
||||
inline void SetState(std::shared_ptr<State> state);
|
||||
|
||||
inline bool Update(float elapsedTime);
|
||||
|
||||
inline StateMachine& operator=(StateMachine&& fsm) = default;
|
||||
StateMachine& operator=(const StateMachine&) = delete;
|
||||
|
||||
private:
|
||||
std::shared_ptr<State> m_currentState;
|
||||
std::shared_ptr<State> m_nextState;
|
||||
std::vector<std::shared_ptr<State>> m_states;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
|
||||
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <NDK/StateMachine.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace Ndk
|
||||
|
|
@ -11,7 +10,7 @@ namespace Ndk
|
|||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::StateMachine
|
||||
* \brief NDK class that represents a state machine, to represent the multiple states of your program
|
||||
* \brief NDK class that represents a state machine, to represent the multiple states of your program as a stack
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
@ -23,61 +22,153 @@ namespace Ndk
|
|||
* \remark Produces a NazaraAssert if nullptr is given
|
||||
*/
|
||||
|
||||
inline StateMachine::StateMachine(std::shared_ptr<State> originalState) :
|
||||
m_currentState(std::move(originalState))
|
||||
inline StateMachine::StateMachine(std::shared_ptr<State> originalState)
|
||||
{
|
||||
NazaraAssert(m_currentState, "StateMachine must have a state to begin with");
|
||||
m_currentState->Enter(*this);
|
||||
NazaraAssert(originalState, "StateMachine must have a state to begin with");
|
||||
PushState(std::move(originalState));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destructs the object
|
||||
*
|
||||
* \remark Calls "Leave" on the state
|
||||
* \remark Calls "Leave" on all the states
|
||||
*/
|
||||
|
||||
inline StateMachine::~StateMachine()
|
||||
{
|
||||
m_currentState->Leave(*this);
|
||||
for (std::shared_ptr<State>& state : m_states)
|
||||
state->Leave(*this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Changes the current state of the machine
|
||||
* \brief Replaces the current state on the top of the machine
|
||||
*
|
||||
* \param state Next state to represent
|
||||
* \param state State to replace the top one if it is nullptr, no action is performed
|
||||
*/
|
||||
|
||||
inline void StateMachine::ChangeState(std::shared_ptr<State> state)
|
||||
{
|
||||
m_nextState = std::move(state);
|
||||
if (state)
|
||||
{
|
||||
PopState();
|
||||
PushState(std::move(state));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current state of the machine
|
||||
* \brief Gets the current state on the top of the machine
|
||||
* \return A constant reference to the state
|
||||
*
|
||||
* \remark The stack is supposed to be non empty, otherwise it is undefined behaviour
|
||||
*
|
||||
* \see PopStatesUntil
|
||||
*/
|
||||
|
||||
inline const std::shared_ptr<State>& StateMachine::GetCurrentState() const
|
||||
{
|
||||
return m_currentState;
|
||||
return m_states.back();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the state
|
||||
* \return True if update is successful
|
||||
* \brief Checks whether the state is on the top of the machine
|
||||
* \return true If it is the case
|
||||
*
|
||||
* \param state State to compare the top with
|
||||
*/
|
||||
|
||||
inline bool StateMachine::IsTopState(const State* state) const
|
||||
{
|
||||
if (m_states.empty())
|
||||
return false;
|
||||
|
||||
return m_states.back().get() == state;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pops the state on the top of the machine
|
||||
* \return Old state on the top, nullptr if stack was empty
|
||||
*
|
||||
* \remark This method can completely empty the stack
|
||||
*/
|
||||
|
||||
inline std::shared_ptr<State> StateMachine::PopState()
|
||||
{
|
||||
if (m_states.empty())
|
||||
return nullptr;
|
||||
|
||||
m_states.back()->Leave(*this);
|
||||
std::shared_ptr<State> oldTopState = std::move(m_states.back());
|
||||
m_states.pop_back();
|
||||
return oldTopState;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pops all the states of the machine until a specific one is reached
|
||||
* \return true If that specific state is on top, false if stack is empty
|
||||
*
|
||||
* \param state State to find on the stack if it is nullptr, no action is performed
|
||||
*
|
||||
* \remark This method can completely empty the stack
|
||||
*/
|
||||
|
||||
inline bool StateMachine::PopStatesUntil(std::shared_ptr<State> state)
|
||||
{
|
||||
if (!state)
|
||||
return false;
|
||||
|
||||
while (!m_states.empty() && !IsTopState(state.get()))
|
||||
PopState();
|
||||
|
||||
return !m_states.empty();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pushes a new state on the top of the machine
|
||||
*
|
||||
* \param state Next state to represent if it is nullptr, it performs no action
|
||||
*
|
||||
* \remark Produces a NazaraAssert if the same state is pushed two times on the stack
|
||||
*/
|
||||
|
||||
inline void StateMachine::PushState(std::shared_ptr<State> state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
NazaraAssert(std::find(m_states.begin(), m_states.end(), state) == m_states.end(), "The same state was pushed two times");
|
||||
|
||||
m_states.push_back(std::move(state));
|
||||
m_states.back()->Enter(*this);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pops every states of the machine to put a new one
|
||||
*
|
||||
* \param state State to reset the stack with if it is nullptr, no action is performed
|
||||
*/
|
||||
|
||||
inline void StateMachine::SetState(std::shared_ptr<State> state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
while (!m_states.empty())
|
||||
PopState();
|
||||
|
||||
PushState(std::move(state));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates all the states
|
||||
* \return true If update is successful for everyone of them
|
||||
*
|
||||
* \param elapsedTime Delta time used for the update
|
||||
*/
|
||||
|
||||
inline bool StateMachine::Update(float elapsedTime)
|
||||
{
|
||||
if (m_nextState)
|
||||
{
|
||||
m_currentState->Leave(*this);
|
||||
m_currentState = std::move(m_nextState);
|
||||
m_currentState->Enter(*this);
|
||||
}
|
||||
|
||||
return m_currentState->Update(*this, elapsedTime);
|
||||
return std::all_of(m_states.begin(), m_states.end(), [=](std::shared_ptr<State>& state) {
|
||||
return state->Update(*this, elapsedTime);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Ndk
|
|||
void Clear() noexcept;
|
||||
const EntityHandle& CloneEntity(EntityId id);
|
||||
|
||||
const EntityHandle& GetEntity(EntityId id);
|
||||
inline const EntityHandle& GetEntity(EntityId id);
|
||||
inline const EntityList& GetEntities() const;
|
||||
inline BaseSystem& GetSystem(SystemIndex index);
|
||||
template<typename SystemType> SystemType& GetSystem();
|
||||
|
|
@ -55,7 +55,7 @@ namespace Ndk
|
|||
inline bool HasSystem(SystemIndex index) const;
|
||||
template<typename SystemType> bool HasSystem() const;
|
||||
|
||||
void KillEntity(Entity* entity);
|
||||
inline void KillEntity(Entity* entity);
|
||||
inline void KillEntities(const EntityVector& list);
|
||||
|
||||
inline bool IsEntityValid(const Entity* entity) const;
|
||||
|
|
|
|||
|
|
@ -164,18 +164,53 @@ namespace Ndk
|
|||
return HasSystem(index);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Marks an entity for deletion
|
||||
*
|
||||
* \param Pointer to the entity
|
||||
*
|
||||
* \remark If the entity pointer is invalid, nothing is done
|
||||
* \remark For safety, entities are not killed until the next world update
|
||||
*/
|
||||
inline void World::KillEntity(Entity* entity)
|
||||
{
|
||||
if (IsEntityValid(entity))
|
||||
m_killedEntities.UnboundedSet(entity->GetId(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Kills a set of entities
|
||||
*
|
||||
* This function has the same effect as calling KillEntity for every entity contained in the vector
|
||||
*
|
||||
* \param list Set of entities to kill
|
||||
*/
|
||||
|
||||
inline void World::KillEntities(const EntityVector& list)
|
||||
{
|
||||
for (const EntityHandle& entity : list)
|
||||
KillEntity(entity);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets an entity
|
||||
* \return A constant reference to a handle of the entity
|
||||
*
|
||||
* \param id Identifier of the entity
|
||||
*
|
||||
* \remark Handle referenced by this function can move in memory when updating the world, do not keep a reference to a handle from a world update to another
|
||||
* \remark If an invalid identifier is provided, an error got triggered and an invalid handle is returned
|
||||
*/
|
||||
inline const EntityHandle& World::GetEntity(EntityId id)
|
||||
{
|
||||
if (IsEntityIdValid(id))
|
||||
return m_entityBlocks[id]->handle;
|
||||
else
|
||||
{
|
||||
NazaraError("Invalid ID");
|
||||
return EntityHandle::InvalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether or not an entity is valid
|
||||
* \return true If it is the case
|
||||
|
|
@ -266,6 +301,7 @@ namespace Ndk
|
|||
{
|
||||
m_aliveEntities = std::move(world.m_aliveEntities);
|
||||
m_dirtyEntities = std::move(world.m_dirtyEntities);
|
||||
m_entityBlocks = std::move(world.m_entityBlocks);
|
||||
m_freeIdList = std::move(world.m_freeIdList);
|
||||
m_killedEntities = std::move(world.m_killedEntities);
|
||||
m_orderedSystems = std::move(world.m_orderedSystems);
|
||||
|
|
@ -285,7 +321,7 @@ namespace Ndk
|
|||
|
||||
inline void World::Invalidate()
|
||||
{
|
||||
m_dirtyEntities.Resize(m_entities.size(), false);
|
||||
m_dirtyEntities.Resize(m_entityBlocks.size(), false);
|
||||
m_dirtyEntities.Set(true); // Activation of all bits
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace Ndk
|
|||
HandledObject(std::move(entity)),
|
||||
m_components(std::move(entity.m_components)),
|
||||
m_componentBits(std::move(entity.m_componentBits)),
|
||||
m_removedComponentBits(std::move(entity.m_removedComponentBits)),
|
||||
m_systemBits(std::move(entity.m_systemBits)),
|
||||
m_id(entity.m_id),
|
||||
m_world(entity.m_world),
|
||||
|
|
|
|||
|
|
@ -68,12 +68,14 @@ namespace Ndk
|
|||
m_freeIdList.pop_back();
|
||||
|
||||
entBlock = &m_entities[id];
|
||||
entBlock->handle.Reset(&entBlock->entity); //< Reset handle (as it was reset when entity got destroyed)
|
||||
|
||||
m_entityBlocks[id] = entBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We allocate a new entity
|
||||
id = static_cast<Ndk::EntityId>(m_entities.size());
|
||||
id = static_cast<Ndk::EntityId>(m_entityBlocks.size());
|
||||
|
||||
if (m_entities.capacity() > m_entities.size())
|
||||
{
|
||||
|
|
@ -114,6 +116,7 @@ namespace Ndk
|
|||
// First, destruction of entities, then handles
|
||||
// This is made to avoid that handle warn uselessly entities before their destruction
|
||||
m_entities.clear();
|
||||
m_entityBlocks.clear();
|
||||
|
||||
m_aliveEntities.Clear();
|
||||
m_dirtyEntities.Clear();
|
||||
|
|
@ -138,7 +141,7 @@ namespace Ndk
|
|||
return EntityHandle::InvalidHandle;
|
||||
}
|
||||
|
||||
EntityHandle clone = CreateEntity();
|
||||
const EntityHandle& clone = CreateEntity();
|
||||
|
||||
const Nz::Bitset<>& componentBits = original->GetComponentBits();
|
||||
for (std::size_t i = componentBits.FindFirst(); i != componentBits.npos; i = componentBits.FindNext(i))
|
||||
|
|
@ -150,40 +153,6 @@ namespace Ndk
|
|||
return GetEntity(clone->GetId());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Kills an entity
|
||||
*
|
||||
* \param Pointer to the entity
|
||||
*
|
||||
* \remark No change is done if entity is invalid
|
||||
*/
|
||||
|
||||
void World::KillEntity(Entity* entity)
|
||||
{
|
||||
if (IsEntityValid(entity))
|
||||
m_killedEntities.UnboundedSet(entity->GetId(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets an entity
|
||||
* \return A constant reference to the modified entity
|
||||
*
|
||||
* \param id Identifier of the entity
|
||||
*
|
||||
* \remark Produces a NazaraError if entity identifier is not valid
|
||||
*/
|
||||
|
||||
const EntityHandle& World::GetEntity(EntityId id)
|
||||
{
|
||||
if (IsEntityIdValid(id))
|
||||
return m_entities[id].handle;
|
||||
else
|
||||
{
|
||||
NazaraError("Invalid ID");
|
||||
return EntityHandle::InvalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Updates the world
|
||||
*
|
||||
|
|
@ -205,6 +174,10 @@ namespace Ndk
|
|||
m_entities.push_back(std::move(*blockPtr));
|
||||
|
||||
m_waitingEntities.clear();
|
||||
|
||||
// Update entity blocks pointers
|
||||
for (std::size_t i = 0; i < m_entities.size(); ++i)
|
||||
m_entityBlocks[i] = &m_entities[i];
|
||||
}
|
||||
|
||||
// Handle killed entities before last call
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace Nz
|
|||
std::vector<BillboardData> billboards;
|
||||
};
|
||||
|
||||
typedef std::map<const Material*, BatchedBillboardEntry, MaterialComparator> BatchedBillboardContainer;
|
||||
using BatchedBillboardContainer = std::map<const Material*, BatchedBillboardEntry, MaterialComparator>;
|
||||
|
||||
struct BatchedBillboardPipelineEntry
|
||||
{
|
||||
|
|
@ -81,7 +81,7 @@ namespace Nz
|
|||
bool enabled = false;
|
||||
};
|
||||
|
||||
typedef std::map<const MaterialPipeline*, BatchedBillboardPipelineEntry, MaterialPipelineComparator> BillboardPipelineBatches;
|
||||
using BillboardPipelineBatches = std::map<const MaterialPipeline*, BatchedBillboardPipelineEntry, MaterialPipelineComparator>;
|
||||
|
||||
/// Sprites
|
||||
struct SpriteChain_XYZ_Color_UV
|
||||
|
|
@ -97,7 +97,7 @@ namespace Nz
|
|||
std::vector<SpriteChain_XYZ_Color_UV> spriteChains;
|
||||
};
|
||||
|
||||
typedef std::map<const Texture*, BatchedSpriteEntry> SpriteOverlayBatches;
|
||||
using SpriteOverlayBatches = std::map<const Texture*, BatchedSpriteEntry>;
|
||||
|
||||
struct BatchedBasicSpriteEntry
|
||||
{
|
||||
|
|
@ -107,7 +107,7 @@ namespace Nz
|
|||
bool enabled = false;
|
||||
};
|
||||
|
||||
typedef std::map<const Material*, BatchedBasicSpriteEntry, MaterialComparator> SpriteMaterialBatches;
|
||||
using SpriteMaterialBatches = std::map<const Material*, BatchedBasicSpriteEntry, MaterialComparator>;
|
||||
|
||||
struct BatchedSpritePipelineEntry
|
||||
{
|
||||
|
|
@ -115,7 +115,7 @@ namespace Nz
|
|||
bool enabled = false;
|
||||
};
|
||||
|
||||
typedef std::map<const MaterialPipeline*, BatchedSpritePipelineEntry, MaterialPipelineComparator> SpritePipelineBatches;
|
||||
using SpritePipelineBatches = std::map<const MaterialPipeline*, BatchedSpritePipelineEntry, MaterialPipelineComparator>;
|
||||
|
||||
/// Meshes
|
||||
struct MeshDataComparator
|
||||
|
|
@ -132,7 +132,7 @@ namespace Nz
|
|||
Spheref squaredBoundingSphere;
|
||||
};
|
||||
|
||||
typedef std::map<MeshData, MeshInstanceEntry, MeshDataComparator> MeshInstanceContainer;
|
||||
using MeshInstanceContainer = std::map<MeshData, MeshInstanceEntry, MeshDataComparator>;
|
||||
|
||||
struct BatchedModelEntry
|
||||
{
|
||||
|
|
@ -142,7 +142,7 @@ namespace Nz
|
|||
bool enabled = false;
|
||||
};
|
||||
|
||||
typedef std::map<const Material*, BatchedModelEntry, MaterialComparator> MeshMaterialBatches;
|
||||
using MeshMaterialBatches = std::map<const Material*, BatchedModelEntry, MaterialComparator>;
|
||||
|
||||
struct BatchedMaterialEntry
|
||||
{
|
||||
|
|
@ -150,7 +150,7 @@ namespace Nz
|
|||
MeshMaterialBatches materialMap;
|
||||
};
|
||||
|
||||
typedef std::map<const MaterialPipeline*, BatchedMaterialEntry, MaterialPipelineComparator> MeshPipelineBatches;
|
||||
using MeshPipelineBatches = std::map<const MaterialPipeline*, BatchedMaterialEntry, MaterialPipelineComparator>;
|
||||
|
||||
struct TransparentModelData
|
||||
{
|
||||
|
|
@ -160,7 +160,7 @@ namespace Nz
|
|||
const Material* material;
|
||||
};
|
||||
|
||||
typedef std::vector<std::size_t> TransparentModelContainer;
|
||||
using TransparentModelContainer = std::vector<std::size_t>;
|
||||
|
||||
struct Layer
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ namespace Nz
|
|||
|
||||
struct Callback
|
||||
{
|
||||
ContactEndCallback endCallback;
|
||||
ContactPreSolveCallback preSolveCallback;
|
||||
ContactPostSolveCallback postSolveCallback;
|
||||
ContactStartCallback startCallback;
|
||||
ContactEndCallback endCallback = nullptr;
|
||||
ContactPreSolveCallback preSolveCallback = nullptr;
|
||||
ContactPostSolveCallback postSolveCallback = nullptr;
|
||||
ContactStartCallback startCallback = nullptr;
|
||||
void* userdata;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ SCENARIO("BaseSystem", "[NDK][BASESYSTEM]")
|
|||
|
||||
WHEN("We add an entity")
|
||||
{
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
entity->AddComponent<Ndk::VelocityComponent>();
|
||||
|
||||
THEN("System should have it")
|
||||
|
|
@ -50,7 +50,7 @@ SCENARIO("BaseSystem", "[NDK][BASESYSTEM]")
|
|||
|
||||
WHEN("We add an entity with excluded component")
|
||||
{
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
entity->AddComponent<Ndk::VelocityComponent>();
|
||||
entity->AddComponent<Ndk::NodeComponent>();
|
||||
|
||||
|
|
|
|||
|
|
@ -57,18 +57,18 @@ SCENARIO("Entity", "[NDK][ENTITY]")
|
|||
{
|
||||
Ndk::World world;
|
||||
Ndk::BaseSystem& system = world.AddSystem<UpdateSystem>();
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
|
||||
WHEN("We add our UpdateComponent")
|
||||
{
|
||||
UpdatableComponent& updatableComponent = entity->AddComponent<UpdatableComponent>();
|
||||
REQUIRE(!updatableComponent.IsUpdated());
|
||||
CHECK(!updatableComponent.IsUpdated());
|
||||
|
||||
THEN("Update the world should update the entity's component")
|
||||
{
|
||||
world.Update(1.f);
|
||||
UpdatableComponent& updatableComponentGet = entity->GetComponent<UpdatableComponent>();
|
||||
REQUIRE(updatableComponentGet.IsUpdated());
|
||||
CHECK(updatableComponentGet.IsUpdated());
|
||||
}
|
||||
|
||||
THEN("Update the world should not update the entity's component if it's disabled")
|
||||
|
|
@ -76,14 +76,14 @@ SCENARIO("Entity", "[NDK][ENTITY]")
|
|||
entity->Enable(false);
|
||||
world.Update(1.f);
|
||||
UpdatableComponent& updatableComponentGet = entity->GetComponent<UpdatableComponent>();
|
||||
REQUIRE(!updatableComponentGet.IsUpdated());
|
||||
CHECK(!updatableComponentGet.IsUpdated());
|
||||
}
|
||||
|
||||
THEN("We can remove its component")
|
||||
{
|
||||
entity->RemoveComponent(Ndk::GetComponentIndex<UpdatableComponent>());
|
||||
world.Update(1.f);
|
||||
REQUIRE(!entity->HasComponent<UpdatableComponent>());
|
||||
CHECK(!entity->HasComponent<UpdatableComponent>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ SCENARIO("Entity", "[NDK][ENTITY]")
|
|||
|
||||
THEN("It's no more valid")
|
||||
{
|
||||
REQUIRE(!world.IsEntityValid(entity));
|
||||
CHECK(!world.IsEntityValid(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]")
|
|||
GIVEN("A world & an entity")
|
||||
{
|
||||
Ndk::World world;
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
|
||||
WHEN("We set the ownership of the entity to our owner")
|
||||
{
|
||||
|
|
@ -15,14 +15,14 @@ SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]")
|
|||
|
||||
THEN("Entity is still valid")
|
||||
{
|
||||
REQUIRE(entity.IsValid());
|
||||
CHECK(entity.IsValid());
|
||||
}
|
||||
|
||||
THEN("Resetting or getting out of scope is no more valid")
|
||||
{
|
||||
entityOwner.Reset();
|
||||
world.Update(1.f);
|
||||
REQUIRE(!entity.IsValid());
|
||||
CHECK(!entity.IsValid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,21 +28,79 @@ class TestState : public Ndk::State
|
|||
bool m_isUpdated;
|
||||
};
|
||||
|
||||
class SecondTestState : public Ndk::State
|
||||
{
|
||||
public:
|
||||
void Enter(Ndk::StateMachine& /*fsm*/) override
|
||||
{
|
||||
m_isUpdated = false;
|
||||
}
|
||||
|
||||
bool IsUpdated() const
|
||||
{
|
||||
return m_isUpdated;
|
||||
}
|
||||
|
||||
void Leave(Ndk::StateMachine& /*fsm*/) override
|
||||
{
|
||||
}
|
||||
|
||||
bool Update(Ndk::StateMachine& fsm, float /*elapsedTime*/) override
|
||||
{
|
||||
if (fsm.IsTopState(this))
|
||||
m_isUpdated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isUpdated;
|
||||
};
|
||||
|
||||
SCENARIO("State & StateMachine", "[NDK][STATE]")
|
||||
{
|
||||
GIVEN("A statemachine with our TestState")
|
||||
GIVEN("A statemachine with our test states")
|
||||
{
|
||||
std::shared_ptr<TestState> testState = std::make_shared<TestState>();
|
||||
Ndk::StateMachine stateMachine(testState);
|
||||
std::shared_ptr<SecondTestState> secondTestState = std::make_shared<SecondTestState>();
|
||||
Ndk::StateMachine stateMachine(secondTestState);
|
||||
stateMachine.PushState(testState);
|
||||
REQUIRE(!testState->IsUpdated());
|
||||
REQUIRE(!secondTestState->IsUpdated());
|
||||
|
||||
WHEN("We update our machine")
|
||||
{
|
||||
stateMachine.Update(1.f);
|
||||
|
||||
THEN("Our state has been updated")
|
||||
THEN("Our state on the top has been updated but not the bottom one")
|
||||
{
|
||||
REQUIRE(stateMachine.IsTopState(testState.get()));
|
||||
REQUIRE(!stateMachine.IsTopState(secondTestState.get()));
|
||||
|
||||
REQUIRE(testState->IsUpdated());
|
||||
REQUIRE(!secondTestState->IsUpdated());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We exchange the states' positions while emptying the stack")
|
||||
{
|
||||
REQUIRE(stateMachine.PopStatesUntil(secondTestState));
|
||||
REQUIRE(stateMachine.IsTopState(secondTestState.get()));
|
||||
|
||||
std::shared_ptr<Ndk::State> oldState = stateMachine.PopState();
|
||||
REQUIRE(stateMachine.PopState() == nullptr);
|
||||
|
||||
stateMachine.SetState(testState);
|
||||
stateMachine.PushState(oldState);
|
||||
|
||||
stateMachine.Update(1.f);
|
||||
|
||||
THEN("Both states should be updated")
|
||||
{
|
||||
REQUIRE(!stateMachine.IsTopState(testState.get()));
|
||||
REQUIRE(stateMachine.IsTopState(secondTestState.get()));
|
||||
|
||||
REQUIRE(testState->IsUpdated());
|
||||
REQUIRE(secondTestState->IsUpdated());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ SCENARIO("World", "[NDK][WORLD]")
|
|||
AND_WHEN("We update our world with our entity")
|
||||
{
|
||||
REQUIRE(&world.GetSystem(UpdateSystem::systemIndex) == &world.GetSystem<UpdateSystem>());
|
||||
const Ndk::EntityHandle& entity = world.CreateEntity();
|
||||
Ndk::EntityHandle entity = world.CreateEntity();
|
||||
UpdatableComponent& component = entity->AddComponent<UpdatableComponent>();
|
||||
|
||||
THEN("Our entity component must be updated")
|
||||
|
|
|
|||
Loading…
Reference in New Issue