Merge pull request #69 from Gawaboumga/Documentation-SDK

Documentation sdk

Former-commit-id: 9e3747db82d92e546b7130e448d873a44abd3e9f [formerly 95bdbe47474230d38dc0db5081153c493a72c52f] [formerly 82a3c12f7a93ad7ef06382772d77138752e3aee8 [formerly 1b17f83fe753c74b553d08ce90dbeea6258524ae]]
Former-commit-id: d601e3115eac024da86ecdcf58ad7d0330c39a18 [formerly 65d8537930d8ae18ff90de4399d809031472c269]
Former-commit-id: 7ee513182b637a4c67f9cc97d78754987a4c9949
This commit is contained in:
Lynix 2016-08-23 12:54:10 +02:00 committed by GitHub
commit 0f1c629d46
80 changed files with 3431 additions and 156 deletions

View File

@ -6,7 +6,15 @@
namespace Ndk
{
///TODO: constexpr avec le C++14
/*!
* \ingroup NDK
* \brief Builds a component id based on a name
* \return Identifier for the component
*
* \param name Name to generate id from
*/
///TODO: constexpr with the C++14
template<unsigned int N>
ComponentId BuildComponentId(const char (&name)[N])
{
@ -19,18 +27,38 @@ namespace Ndk
return componentId;
}
/*!
* \ingroup NDK
* \brief Gets the component id of a component
* \return Identifier for the component
*/
template<typename ComponentType>
ComponentIndex GetComponentIndex()
{
return ComponentType::componentIndex;
}
/*!
* \ingroup NDK
* \brief Gets the system id of a system
* \return Identifier for the system
*/
template<typename SystemType>
SystemIndex GetSystemIndex()
{
return SystemType::systemIndex;
}
/*!
* \ingroup NDK
* \brief Initializes the a component
* \return Identifier for the component
*
* \param name Name to generate id from
*/
template<typename ComponentType, unsigned int N>
ComponentIndex InitializeComponent(const char (&name)[N])
{
@ -38,6 +66,12 @@ namespace Ndk
return ComponentType::componentIndex;
}
/*!
* \ingroup NDK
* \brief Initializes the a system
* \return Identifier for the system
*/
template<typename SystemType>
SystemIndex InitializeSystem()
{
@ -45,12 +79,26 @@ namespace Ndk
return SystemType::systemIndex;
}
/*!
* \brief Checks whether the parameter is a component
* \return true If it is the case
*
* \param component Component to check
*/
template<typename ComponentType, typename C>
bool IsComponent(C& component)
{
return component.GetIndex() == GetComponentIndex<ComponentType>();
}
/*!
* \brief Checks whether the parameter is a system
* \return true If it is the case
*
* \param system System to check
*/
template<typename SystemType, typename S>
bool IsSystem(S& system)
{

View File

@ -8,6 +8,12 @@
namespace Ndk
{
/*!
* \brief Constructs an Application object by default
*
* \remark Produces a NazaraAssert if there's more than one application instance currently running
*/
inline Application::Application() :
#ifndef NDK_SERVER
m_exitOnClosedWindows(true),
@ -24,6 +30,10 @@ namespace Ndk
Sdk::Initialize();
}
/*!
* \brief Destructs the object
*/
inline Application::~Application()
{
m_worlds.clear();
@ -31,13 +41,20 @@ namespace Ndk
m_windows.clear();
#endif
// Libération du SDK
// Free of SDK
Sdk::Uninitialize();
// Libération automatique des modules
// Automatic free of modules
s_application = nullptr;
}
/*!
* \brief Adds a window to the application
* \return A reference to the newly created windows
*
* \param args Arguments used to create the window
*/
#ifndef NDK_SERVER
template<typename T, typename... Args>
T& Application::AddWindow(Args&&... args)
@ -49,6 +66,13 @@ namespace Ndk
}
#endif
/*!
* \brief Adds a world to the application
* \return A reference to the newly created world
*
* \param args Arguments used to create the world
*/
template<typename... Args>
World& Application::AddWorld(Args&&... args)
{
@ -56,11 +80,22 @@ namespace Ndk
return m_worlds.back();
}
/*!
* \brief Gets the update time of the application
* \return Update rate
*/
inline float Application::GetUpdateTime() const
{
return m_updateTime;
}
/*!
* \brief Makes the application exit when there's no more open window
*
* \param exitOnClosedWindows Should exit be called when no more window is open
*/
#ifndef NDK_SERVER
inline void Application::MakeExitOnLastWindowClosed(bool exitOnClosedWindows)
{
@ -68,11 +103,20 @@ namespace Ndk
}
#endif
/*!
* \brief Quits the application
*/
inline void Application::Quit()
{
m_shouldQuit = true;
}
/*!
* \brief Gets the singleton instance of the application
* \return Singleton application
*/
inline Application* Application::Instance()
{
return s_application;

View File

@ -27,7 +27,7 @@ namespace Ndk
BaseComponent(BaseComponent&&) = default;
virtual ~BaseComponent();
virtual BaseComponent* Clone() const = 0;
virtual std::unique_ptr<BaseComponent> Clone() const = 0;
ComponentIndex GetIndex() const;

View File

@ -7,34 +7,60 @@
namespace Ndk
{
/*!
* \brief Constructs a BaseComponent object with an index
*
* \param index Index of the component
*/
inline BaseComponent::BaseComponent(ComponentIndex index) :
m_componentIndex(index),
m_entity(nullptr)
{
}
/*!
* \brief Gets the index of the component
* \return Index of the component
*/
inline ComponentIndex BaseComponent::GetIndex() const
{
return m_componentIndex;
}
/*!
* \brief Gets the maximal index of the components
* \return Index of the maximal component
*/
inline ComponentIndex BaseComponent::GetMaxComponentIndex()
{
return static_cast<ComponentIndex>(s_entries.size());
}
/*!
* \brief Registers a component
* \return Index of the registered component
*
* \param id Index of the component
* \param factory Factory to create the component
*
* \remark Produces a NazaraAssert if the identifier is already in use
*/
inline ComponentIndex BaseComponent::RegisterComponent(ComponentId id, Factory factoryFunc)
{
// Nous allons rajouter notre composant à la fin
// We add our component to the end
ComponentIndex index = static_cast<ComponentIndex>(s_entries.size());
s_entries.resize(index + 1);
// On récupère et on affecte
// We retrieve it and affect it
ComponentEntry& entry = s_entries.back();
entry.factory = factoryFunc;
entry.id = id;
// Une petite assertion pour s'assurer que l'identifiant n'est pas déjà utilisé
// We ensure that id is not already in use
NazaraAssert(s_idToIndex.find(id) == s_idToIndex.end(), "This id is already in use");
s_idToIndex[id] = index;
@ -42,6 +68,10 @@ namespace Ndk
return index;
}
/*!
* \brief Sets the entity on which the component operates
*/
inline void BaseComponent::SetEntity(Entity* entity)
{
if (m_entity != entity)
@ -55,12 +85,21 @@ namespace Ndk
}
}
/*!
* \brief Initializes the BaseComponent
* \return true
*/
inline bool BaseComponent::Initialize()
{
// Rien à faire
// Nothing to do
return true;
}
/*!
* \brief Uninitializes the BaseComponent
*/
inline void BaseComponent::Uninitialize()
{
s_entries.clear();

View File

@ -29,7 +29,7 @@ namespace Ndk
inline void Enable(bool enable = true);
virtual BaseSystem* Clone() const = 0;
virtual std::unique_ptr<BaseSystem> Clone() const = 0;
bool Filters(const Entity* entity) const;

View File

@ -8,6 +8,12 @@
namespace Ndk
{
/*!
* \brief Constructs a BaseSystem object with an index
*
* \param systemId Index of the system
*/
inline BaseSystem::BaseSystem(SystemIndex systemId) :
m_updateEnabled(true),
m_systemIndex(systemId)
@ -15,6 +21,12 @@ namespace Ndk
SetUpdateRate(30);
}
/*!
* \brief Constructs a BaseSystem object by copy semantic
*
* \param system System to copy
*/
inline BaseSystem::BaseSystem(const BaseSystem& system) :
m_excludedComponents(system.m_excludedComponents),
m_requiredComponents(system.m_requiredComponents),
@ -25,36 +37,74 @@ namespace Ndk
{
}
/*!
* \brief Enables the system
*
* \param enable Should the system be enabled
*/
inline void BaseSystem::Enable(bool enable)
{
m_updateEnabled = enable;
}
/*!
* \brief Gets every entities that system handle
* \return A constant reference to the list of entities
*/
inline const std::vector<EntityHandle>& BaseSystem::GetEntities() const
{
return m_entities;
}
/*!
* \brief Gets the index of the system
* \return Index of the system
*/
inline SystemIndex BaseSystem::GetIndex() const
{
return m_systemIndex;
}
/*!
* \brief Gets the rate of update for the system
* \return Update rate
*/
inline float BaseSystem::GetUpdateRate() const
{
return (m_updateRate > 0.f) ? 1.f / m_updateRate : 0.f;
}
/*!
* \brief Gets the world on which the system operate
* \return World in which the system is
*/
inline World& BaseSystem::GetWorld() const
{
return *m_world;
}
/*!
* \brief Checks whether or not the system is enabled
* \return true If it is the case
*/
inline bool BaseSystem::IsEnabled() const
{
return m_updateEnabled;
}
/*!
* \brief Checks whether or not the system has the entity
* \return true If it is the case
*
* \param entity Pointer to the entity
*/
inline bool BaseSystem::HasEntity(const Entity* entity) const
{
if (!entity)
@ -63,12 +113,24 @@ namespace Ndk
return m_entityBits.UnboundedTest(entity->GetId());
}
/*!
* \brief Sets the rate of update for the system
*
* \param updatePerSecond Update rate, 0 means as much as possible
*/
inline void BaseSystem::SetUpdateRate(float updatePerSecond)
{
m_updateCounter = 0.f;
m_updateRate = (updatePerSecond > 0.f) ? 1.f / updatePerSecond : 0.f; // 0.f means no limit
}
/*!
* \brief Updates the system
*
* \param elapsedTime Delta time used for the update
*/
inline void BaseSystem::Update(float elapsedTime)
{
if (!IsEnabled())
@ -88,6 +150,10 @@ namespace Ndk
OnUpdate(elapsedTime);
}
/*!
* \brief Excludes some component from the system
*/
template<typename ComponentType>
void BaseSystem::Excludes()
{
@ -96,6 +162,10 @@ namespace Ndk
ExcludesComponent(GetComponentIndex<ComponentType>());
}
/*!
* \brief Excludes some components from the system
*/
template<typename ComponentType1, typename ComponentType2, typename... Rest>
void BaseSystem::Excludes()
{
@ -103,16 +173,31 @@ namespace Ndk
Excludes<ComponentType2, Rest...>();
}
/*!
* \brief Excludes some component from the system by index
*
* \param index Index of the component
*/
inline void BaseSystem::ExcludesComponent(ComponentIndex index)
{
m_excludedComponents.UnboundedSet(index);
}
/*!
* \brief Gets the next index for the system
* \return Next unique index for the system
*/
inline SystemIndex BaseSystem::GetNextIndex()
{
return s_nextIndex++;
}
/*!
* \brief Requires some component from the system
*/
template<typename ComponentType>
void BaseSystem::Requires()
{
@ -121,6 +206,10 @@ namespace Ndk
RequiresComponent(GetComponentIndex<ComponentType>());
}
/*!
* \brief Requires some components from the system
*/
template<typename ComponentType1, typename ComponentType2, typename... Rest>
void BaseSystem::Requires()
{
@ -128,11 +217,21 @@ namespace Ndk
Requires<ComponentType2, Rest...>();
}
/*!
* \brief Requires some component for the system by index
*
* \param index Index of the component
*/
inline void BaseSystem::RequiresComponent(ComponentIndex index)
{
m_requiredComponents.UnboundedSet(index);
}
/*!
* \brief Requires any component from the system
*/
template<typename ComponentType>
void BaseSystem::RequiresAny()
{
@ -141,6 +240,10 @@ namespace Ndk
RequiresAnyComponent(GetComponentIndex<ComponentType>());
}
/*!
* \brief Requires any components from the system
*/
template<typename ComponentType1, typename ComponentType2, typename... Rest>
void BaseSystem::RequiresAny()
{
@ -148,11 +251,25 @@ namespace Ndk
RequiresAny<ComponentType2, Rest...>();
}
/*!
* \brief Requires any component for the system by index
*
* \param index Index of the component
*/
inline void BaseSystem::RequiresAnyComponent(ComponentIndex index)
{
m_requiredAnyComponents.UnboundedSet(index);
}
/*!
* \brief Adds an entity to a system
*
* \param entity Pointer to the entity
*
* \remark Produces a NazaraAssert if entity is invalid
*/
inline void BaseSystem::AddEntity(Entity* entity)
{
NazaraAssert(entity, "Invalid entity");
@ -165,6 +282,14 @@ namespace Ndk
OnEntityAdded(entity);
}
/*!
* \brief Removes an entity to a system
*
* \param entity Pointer to the entity
*
* \remark Produces a NazaraAssert if entity is invalid
*/
inline void BaseSystem::RemoveEntity(Entity* entity)
{
NazaraAssert(entity, "Invalid entity");
@ -172,16 +297,25 @@ namespace Ndk
auto it = std::find(m_entities.begin(), m_entities.end(), *entity);
NazaraAssert(it != m_entities.end(), "Entity is not part of this system");
// Pour éviter de déplacer beaucoup de handles, on swap le dernier avec celui à supprimer
// To avoid moving a lot of handles, we swap and pop
std::swap(*it, m_entities.back());
m_entities.pop_back(); // On le sort du vector
m_entities.pop_back(); // We get it out of the vector
m_entityBits.Reset(entity->GetId());
entity->UnregisterSystem(m_systemIndex);
OnEntityRemoved(entity); // Et on appelle le callback
OnEntityRemoved(entity); // And we alert our callback
}
/*!
* \brief Validates an entity to a system
*
* \param entity Pointer to the entity
* \param justAdded Is the entity newly added
*
* \remark Produces a NazaraAssert if entity is invalid or if system does not hold this entity
*/
inline void BaseSystem::ValidateEntity(Entity* entity, bool justAdded)
{
NazaraAssert(entity, "Invalid entity");
@ -190,11 +324,20 @@ namespace Ndk
OnEntityValidation(entity, justAdded);
}
/*!
* \brief Sets the world on which the system operates
*/
inline void BaseSystem::SetWorld(World* world) noexcept
{
m_world = world;
}
/*!
* \brief Initializes the BaseSystem
* \return true
*/
inline bool BaseSystem::Initialize()
{
s_nextIndex = 0;
@ -202,6 +345,10 @@ namespace Ndk
return true;
}
/*!
* \brief Uninitializes the BaseSystem
*/
inline void BaseSystem::Uninitialize()
{
// Nothing to do

View File

@ -18,7 +18,7 @@ namespace Ndk
Component();
virtual ~Component();
BaseComponent* Clone() const override;
std::unique_ptr<BaseComponent> Clone() const override;
static ComponentIndex RegisterComponent(ComponentId id);

View File

@ -7,6 +7,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::Component<ComponentType>
* \brief NDK class that represents a component for an entity which interacts with a system
*
* \remark This class is meant to be derived as CRTP: "Component<Subtype>"
*/
/*!
* \brief Constructs a Component object by default
*/
template<typename ComponentType>
Component<ComponentType>::Component() :
BaseComponent(GetComponentIndex<ComponentType>())
@ -16,19 +28,30 @@ namespace Ndk
template<typename ComponentType>
Component<ComponentType>::~Component() = default;
/*!
* \brief Clones the component
* \return The clone newly created
*
* \remark The component to clone should be trivially copy constructible
*/
template<typename ComponentType>
BaseComponent* Component<ComponentType>::Clone() const
std::unique_ptr<BaseComponent> Component<ComponentType>::Clone() const
{
///FIXME: Pas encore supporté par GCC (4.9.2)
//static_assert(std::is_trivially_copy_constructible<ComponentType>::value, "ComponentType must be copy-constructible");
return new ComponentType(static_cast<const ComponentType&>(*this));
return std::make_unique<ComponentType>(static_cast<const ComponentType&>(*this));
}
/*!
* \brief Registers the component by assigning it an index
*/
template<typename ComponentType>
ComponentIndex Component<ComponentType>::RegisterComponent(ComponentId id)
{
// On utilise les lambda pour créer une fonction factory
//We use the lambda to create a factory function
auto factory = []() -> BaseComponent*
{
return nullptr; //< Temporary workaround to allow non-default-constructed components, will be updated for serialization
@ -38,11 +61,15 @@ namespace Ndk
return BaseComponent::RegisterComponent(id, factory);
}
/*!
* \brief Registers the component by assigning it an index based on the name
*/
template<typename ComponentType>
template<unsigned int N>
ComponentIndex Component<ComponentType>::RegisterComponent(const char (&name)[N])
{
// On récupère la chaîne de caractère sous la forme d'un nombre qui servira d'identifiant unique
// We convert the string to a number which will be used as unique identifier
ComponentId id = BuildComponentId(name);
return RegisterComponent(id);
}

View File

@ -8,6 +8,10 @@
namespace Ndk
{
/*!
* \brief Constructs an CameraComponent object by default
*/
inline CameraComponent::CameraComponent() :
m_projectionType(Nz::ProjectionType_Perspective),
m_targetRegion(0.f, 0.f, 1.f, 1.f),
@ -25,6 +29,12 @@ namespace Ndk
{
}
/*!
* \brief Constructs a CameraComponent object by copy semantic
*
* \param camera CameraComponent to copy
*/
inline CameraComponent::CameraComponent(const CameraComponent& camera) :
Component(camera),
AbstractViewer(camera),
@ -45,30 +55,51 @@ namespace Ndk
SetTarget(camera.m_target);
}
/*!
* \brief Ensures the frustum is up to date
*/
inline void CameraComponent::EnsureFrustumUpdate() const
{
if (!m_frustumUpdated)
UpdateFrustum();
}
/*!
* \brief Ensures the projection matrix is up to date
*/
inline void CameraComponent::EnsureProjectionMatrixUpdate() const
{
if (!m_projectionMatrixUpdated)
UpdateProjectionMatrix();
}
/*!
* \brief Ensures the view matrix is up to date
*/
inline void CameraComponent::EnsureViewMatrixUpdate() const
{
if (!m_viewMatrixUpdated)
UpdateViewMatrix();
}
/*!
* \brief Ensures the view port is up to date
*/
inline void CameraComponent::EnsureViewportUpdate() const
{
if (!m_viewportUpdated)
UpdateViewport();
}
/*!
* \brief Gets the aspect ratio of the camera
* \return Aspect ratio of the camera
*/
inline float CameraComponent::GetAspectRatio() const
{
EnsureViewportUpdate();
@ -76,11 +107,21 @@ namespace Ndk
return m_aspectRatio;
}
/*!
* \brief Gets the field of view of the camera
* \return Field of view of the camera
*/
inline float CameraComponent::GetFOV() const
{
return m_fov;
}
/*!
* \brief Gets the frutum of the camera
* \return A constant reference to the frustum of the camera
*/
inline const Nz::Frustumf& CameraComponent::GetFrustum() const
{
EnsureFrustumUpdate();
@ -88,11 +129,21 @@ namespace Ndk
return m_frustum;
}
/*!
* \brief Gets the layer of the camera
* \return Layer of the camera
*/
inline unsigned int CameraComponent::GetLayer() const
{
return m_layer;
}
/*!
* \brief Gets the projection matrix of the camera
* \return A constant reference to the projection matrix of the camera
*/
inline const Nz::Matrix4f& CameraComponent::GetProjectionMatrix() const
{
EnsureProjectionMatrixUpdate();
@ -100,26 +151,51 @@ namespace Ndk
return m_projectionMatrix;
}
/*!
* \brief Gets the projection type of the camera
* \return Projection type of the camera
*/
inline Nz::ProjectionType CameraComponent::GetProjectionType() const
{
return m_projectionType;
}
/*!
* \brief Gets the size of the camera
* \return Size of the camera
*/
inline const Nz::Vector2f & CameraComponent::GetSize() const
{
return m_size;
}
/*!
* \brief Gets the target of the camera
* \return A constant reference to the render target of the camera
*/
inline const Nz::RenderTarget* CameraComponent::GetTarget() const
{
return m_target;
}
/*!
* \brief Gets the target region of the camera
* \return A constant reference to the target region of the camera
*/
inline const Nz::Rectf& CameraComponent::GetTargetRegion() const
{
return m_targetRegion;
}
/*!
* \brief Gets the view matrix of the camera
* \return A constant reference to the view matrix of the camera
*/
inline const Nz::Matrix4f& CameraComponent::GetViewMatrix() const
{
EnsureViewMatrixUpdate();
@ -127,6 +203,11 @@ namespace Ndk
return m_viewMatrix;
}
/*!
* \brief Gets the view port of the camera
* \return A constant reference to the view port of the camera
*/
inline const Nz::Recti& CameraComponent::GetViewport() const
{
EnsureViewportUpdate();
@ -134,16 +215,34 @@ namespace Ndk
return m_viewport;
}
/*!
* \brief Gets the Z far distance of the camera
* \return Z far distance of the camera
*/
inline float CameraComponent::GetZFar() const
{
return m_zFar;
}
/*!
* \brief Gets the Z near distance of the camera
* \return Z near distance of the camera
*/
inline float CameraComponent::GetZNear() const
{
return m_zNear;
}
/*!
* \brief Sets the field of view of the camera
*
* \param fov Field of view of the camera
*
* \remark Produces a NazaraAssert if angle is zero
*/
inline void CameraComponent::SetFOV(float fov)
{
NazaraAssert(!Nz::NumberEquals(fov, 0.f), "FOV must be different from zero");
@ -152,6 +251,12 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the projection type of the camera
*
* \param projectionType Projection type of the camera
*/
inline void CameraComponent::SetProjectionType(Nz::ProjectionType projectionType)
{
m_projectionType = projectionType;
@ -159,6 +264,12 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the size of the camera
*
* \param size Size of the camera
*/
inline void CameraComponent::SetSize(const Nz::Vector2f& size)
{
m_size = size;
@ -166,11 +277,24 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the size of the camera
*
* \param width Size in X of the camera
* \param height Size in Y of the camera
*/
inline void CameraComponent::SetSize(float width, float height)
{
SetSize({width, height});
}
/*!
* \brief Sets the target of the camera
*
* \param renderTarget A constant reference to the render target of the camera
*/
inline void CameraComponent::SetTarget(const Nz::RenderTarget* renderTarget)
{
m_target = renderTarget;
@ -186,6 +310,12 @@ namespace Ndk
}
}
/*!
* \brief Sets the target region of the camera
*
* \param region A constant reference to the target region of the camera
*/
inline void CameraComponent::SetTargetRegion(const Nz::Rectf& region)
{
m_targetRegion = region;
@ -193,17 +323,31 @@ namespace Ndk
InvalidateViewport();
}
/*!
* \brief Sets the view port of the camera
*
* \param viewport A constant reference to the view port of the camera
*
* \remark Produces a NazaraAssert if the camera has no target
*/
inline void CameraComponent::SetViewport(const Nz::Recti& viewport)
{
NazaraAssert(m_target, "Component has no render target");
// On calcule la région nécessaire pour produire ce viewport avec la taille actuelle de la cible
float invWidth = 1.f/m_target->GetWidth();
float invHeight = 1.f/m_target->GetHeight();
// We compute the region necessary to make this view port with the actual size of the target
float invWidth = 1.f / m_target->GetWidth();
float invHeight = 1.f / m_target->GetHeight();
SetTargetRegion(Nz::Rectf(invWidth * viewport.x, invHeight * viewport.y, invWidth * viewport.width, invHeight * viewport.height));
}
/*!
* \brief Sets the Z far distance of the camera
*
* \param zFar Z far distance of the camera
*/
inline void CameraComponent::SetZFar(float zFar)
{
m_zFar = zFar;
@ -211,6 +355,14 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Sets the Z near distance of the camera
*
* \param zNear Z near distance of the camera
*
* \remark Produces a NazaraAssert if zNear is zero
*/
inline void CameraComponent::SetZNear(float zNear)
{
NazaraAssert(!Nz::NumberEquals(zNear, 0.f), "zNear cannot be zero");
@ -219,23 +371,39 @@ namespace Ndk
InvalidateProjectionMatrix();
}
/*!
* \brief Invalidates the frustum
*/
inline void CameraComponent::InvalidateFrustum() const
{
m_frustumUpdated = false;
}
/*!
* \brief Invalidates the projection matrix
*/
inline void CameraComponent::InvalidateProjectionMatrix() const
{
m_frustumUpdated = false;
m_projectionMatrixUpdated = false;
}
/*!
* \brief Invalidates the view matrix
*/
inline void CameraComponent::InvalidateViewMatrix() const
{
m_frustumUpdated = false;
m_viewMatrixUpdated = false;
}
/*!
* \brief Invalidates the view port
*/
inline void CameraComponent::InvalidateViewport() const
{
m_frustumUpdated = false;

View File

@ -9,23 +9,47 @@
namespace Ndk
{
/*!
* \brief Constructs a CollisionComponent object with a geometry
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent::CollisionComponent(Nz::PhysGeomRef geom) :
m_geom(std::move(geom)),
m_bodyUpdated(false)
{
}
/*!
* \brief Constructs a CollisionComponent object by copy semantic
*
* \param collision CollisionComponent to copy
*/
inline CollisionComponent::CollisionComponent(const CollisionComponent& collision) :
m_geom(collision.m_geom),
m_bodyUpdated(false)
{
}
/*!
* \brief Gets the geometry representing the entity
* \return A constant reference to the physics geometry
*/
inline const Nz::PhysGeomRef& CollisionComponent::GetGeom() const
{
return m_geom;
}
/*!
* \brief Assigns the geometry to this component
* \return A reference to this
*
* \param geom Reference to a geometry symbolizing the entity
*/
inline CollisionComponent& CollisionComponent::operator=(Nz::PhysGeomRef geom)
{
SetGeom(geom);
@ -33,6 +57,11 @@ namespace Ndk
return *this;
}
/*!
* \brief Gets the static body used by the entity
* \return A pointer to the entity
*/
inline Nz::PhysObject* CollisionComponent::GetStaticBody()
{
return m_staticBody.get();

View File

@ -7,6 +7,12 @@
namespace Ndk
{
/*!
* \brief Constructs a GraphicsComponent object by copy semantic
*
* \param graphicsComponent GraphicsComponent to copy
*/
inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) :
Component(graphicsComponent),
HandledObject(graphicsComponent),
@ -20,6 +26,12 @@ namespace Ndk
Attach(r.renderable, r.data.renderOrder);
}
/*!
* \brief Adds the renderable elements to the render queue
*
* \param renderQueue Queue to be added
*/
inline void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const
{
EnsureTransformMatrixUpdate();
@ -36,6 +48,13 @@ namespace Ndk
}
}
/*!
* \brief Attaches a renderable to the entity
*
* \param renderable Reference to a renderable element
* \param renderOrder Render order of the element
*/
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder)
{
m_renderables.emplace_back(m_transformMatrix);
@ -48,6 +67,10 @@ namespace Ndk
InvalidateBoundingVolume();
}
/*!
* \brief Clears every renderable elements
*/
inline void GraphicsComponent::Clear()
{
m_renderables.clear();
@ -55,6 +78,12 @@ namespace Ndk
InvalidateBoundingVolume();
}
/*!
* \brief Detaches a renderable to the entity
*
* \param renderable Reference to a renderable element
*/
inline void GraphicsComponent::Detach(const Nz::InstancedRenderable* renderable)
{
for (auto it = m_renderables.begin(); it != m_renderables.end(); ++it)
@ -68,18 +97,34 @@ namespace Ndk
}
}
/*!
* \brief Ensures the bounding volume is up to date
*/
inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const
{
if (!m_boundingVolumeUpdated)
UpdateBoundingVolume();
}
/*!
* \brief Ensures the transformation matrix is up to date
*/
inline void GraphicsComponent::EnsureTransformMatrixUpdate() const
{
if (!m_transformMatrixUpdated)
UpdateTransformMatrix();
}
/*!
* \brief Gets the set of renderable elements
*
* \param renderables Pointer to the list of renderables
*
* \remark Produces a NazaraAssert if renderables is invalid
*/
inline void GraphicsComponent::GetAttachedRenderables(RenderableList* renderables) const
{
NazaraAssert(renderables, "Invalid renderable list");
@ -89,11 +134,21 @@ namespace Ndk
renderables->push_back(r.renderable);
}
/*!
* \brief Gets the number of renderable elements attached to the entity
* \return Number of renderable elements
*/
inline std::size_t GraphicsComponent::GetAttachedRenderableCount() const
{
return m_renderables.size();
}
/*!
* \brief Gets the bouding volume of the entity
* \return A constant reference to the bounding volume
*/
inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const
{
EnsureBoundingVolumeUpdate();
@ -101,17 +156,29 @@ namespace Ndk
return m_boundingVolume;
}
/*!
* \brief Invalidates the bounding volume
*/
inline void GraphicsComponent::InvalidateBoundingVolume()
{
m_boundingVolumeUpdated = false;
}
/*!
* \brief Invalidates every renderable elements
*/
inline void GraphicsComponent::InvalidateRenderables()
{
for (Renderable& r : m_renderables)
r.dataUpdated = false;
}
/*!
* \brief Invalidates the transformation matrix
*/
inline void GraphicsComponent::InvalidateTransformMatrix()
{
m_boundingVolumeUpdated = false;

View File

@ -4,6 +4,10 @@
namespace Ndk
{
/*!
* \brief Constructs an LightComponent object with a light type
*/
inline LightComponent::LightComponent(Nz::LightType lightType) :
Nz::Light(lightType)
{

View File

@ -4,16 +4,31 @@
namespace Ndk
{
/*!
* \brief Constructs an ListenerComponent object by default
*/
inline ListenerComponent::ListenerComponent() :
m_isActive(true)
{
}
/*!
* \brief Checks whether the listener is activated
* \param true If it is the case
*/
inline bool ListenerComponent::IsActive() const
{
return m_isActive;
}
/*!
* \brief Enables the listener
*
* \param active Should the listener be active
*/
inline void ListenerComponent::SetActive(bool active)
{
m_isActive = active;

View File

@ -7,6 +7,15 @@
namespace Ndk
{
/*!
* \brief Sets the parent node of the entity
*
* \param entity Pointer to the entity considered as parent
* \param keepDerived Should this component considered as a derived
*
* \remark Produces a NazaraAssert if entity has no component NodeComponent
*/
inline void NodeComponent::SetParent(Entity* entity, bool keepDerived)
{
if (entity)

View File

@ -6,21 +6,42 @@
namespace Ndk
{
/*!
* \brief Constructs an ParticleEmitterComponent object by default
*/
inline ParticleEmitterComponent::ParticleEmitterComponent() :
m_isActive(true)
{
}
/*!
* \brief Enables the emission of particles
*
* \param active Should the emitter be active
*/
inline void Ndk::ParticleEmitterComponent::Enable(bool active)
{
m_isActive = active;
}
/*!
* \brief Checks whether the emission of particles is activated
* \param true If it is the case
*/
inline bool ParticleEmitterComponent::IsActive() const
{
return m_isActive;
}
/*!
* \brief Sets the function use for setting up particles
*
* \param func Function to set up particles
*/
inline void Ndk::ParticleEmitterComponent::SetSetupFunc(SetupFunc func)
{
m_setupFunc = std::move(func);

View File

@ -8,16 +8,45 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::ParticleGroupComponent
* \brief NDK class that represents the component for a group of particles
*/
/*!
* \brief Constructs a ParticleGroupComponent object with a maximal number of particles and a layout
*
* \param maxParticleCount Maximum number of particles to generate
* \param layout Enumeration for the layout of data information for the particles
*/
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout) :
ParticleGroup(maxParticleCount, layout)
{
}
/*!
* \brief Constructs a ParticleGroupComponent object with a maximal number of particles and a particle declaration
*
* \param maxParticleCount Maximum number of particles to generate
* \param declaration Data information for the particles
*/
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration) :
ParticleGroup(maxParticleCount, std::move(declaration))
{
}
/*!
* \brief Adds an emitter to the particles
*
* \param emitter Emitter for the particles
*
* \remark Produces a NazaraAssert if emitter is invalid
* \remark Produces a NazaraAssert if entity has no component of type ParticleEmitterComponent
*/
inline void ParticleGroupComponent::AddEmitter(Entity* emitter)
{
NazaraAssert(emitter && emitter->IsValid(), "Invalid entity");
@ -27,6 +56,16 @@ namespace Ndk
ParticleGroup::AddEmitter(&emitterComponent);
}
/*!
* \brief Removes an emitter to the particles
*
* \param emitter Emitter for the particles to remove
*
* \remark Produces a NazaraAssert if emitter is invalid
* \remark Produces a NazaraAssert if entity has no component of type ParticleEmitterComponent
*/
inline void ParticleGroupComponent::RemoveEmitter(Entity* emitter)
{
NazaraAssert(emitter && emitter->IsValid(), "Invalid entity");

View File

@ -6,12 +6,27 @@
namespace Ndk
{
/*!
* \brief Constructs a PhysicsComponent object by copy semantic
*
* \param physics PhysicsComponent to copy
*/
inline PhysicsComponent::PhysicsComponent(const PhysicsComponent& physics)
{
// Pas de copie de l'objet physique (étant donné que nous n'allons le créer qu'une fois attaché à une entité)
// No copy of physical object (because we only create it when attached to an entity)
NazaraUnused(physics);
}
/*!
* \brief Applies a force to the entity
*
* \param force Force to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::AddForce(const Nz::Vector3f& force, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
@ -19,6 +34,16 @@ namespace Ndk
m_object->AddForce(force, coordSys);
}
/*!
* \brief Applies a force to the entity
*
* \param force Force to apply on the entity
* \param point Point where to apply the force
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::AddForce(const Nz::Vector3f& force, const Nz::Vector3f& point, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
@ -26,13 +51,30 @@ namespace Ndk
m_object->AddForce(force, point, coordSys);
}
/*!
* \brief Applies a torque to the entity
*
* \param torque Torque to apply on the entity
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys)
{
NazaraAssert(m_object, "Invalid physics object");
m_object->AddForce(torque, coordSys);
m_object->AddTorque(torque, coordSys);
}
/*!
* \brief Enables auto sleep of physics object
*
* \param autoSleep Should the physics of the object be disabled when too far from others
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::EnableAutoSleep(bool autoSleep)
{
NazaraAssert(m_object, "Invalid physics object");
@ -40,6 +82,13 @@ namespace Ndk
m_object->EnableAutoSleep(autoSleep);
}
/*!
* \brief Gets the AABB of the physics object
* \return AABB of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Boxf PhysicsComponent::GetAABB() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -47,6 +96,13 @@ namespace Ndk
return m_object->GetAABB();
}
/*!
* \brief Gets the angular velocity of the physics object
* \return Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetAngularVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -54,6 +110,13 @@ namespace Ndk
return m_object->GetAngularVelocity();
}
/*!
* \brief Gets the gravity factor of the physics object
* \return Gravity factor of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent::GetGravityFactor() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -61,6 +124,13 @@ namespace Ndk
return m_object->GetGravityFactor();
}
/*!
* \brief Gets the mass of the physics object
* \return Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline float PhysicsComponent::GetMass() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -68,6 +138,15 @@ namespace Ndk
return m_object->GetMass();
}
/*!
* \brief Gets the gravity center of the physics object
* \return Gravity center of the object
*
* \param coordSys System coordinates to consider
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetMassCenter(Nz::CoordSys coordSys) const
{
NazaraAssert(m_object, "Invalid physics object");
@ -75,6 +154,13 @@ namespace Ndk
return m_object->GetMassCenter(coordSys);
}
/*!
* \brief Gets the matrix of the physics object
* \return Matrix of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline const Nz::Matrix4f& PhysicsComponent::GetMatrix() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -82,6 +168,13 @@ namespace Ndk
return m_object->GetMatrix();
}
/*!
* \brief Gets the position of the physics object
* \return Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetPosition() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -89,6 +182,13 @@ namespace Ndk
return m_object->GetPosition();
}
/*!
* \brief Gets the rotation of the physics object
* \return Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Quaternionf PhysicsComponent::GetRotation() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -96,6 +196,13 @@ namespace Ndk
return m_object->GetRotation();
}
/*!
* \brief Gets the velocity of the physics object
* \return Velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline Nz::Vector3f PhysicsComponent::GetVelocity() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -103,6 +210,13 @@ namespace Ndk
return m_object->GetVelocity();
}
/*!
* \brief Checks whether the auto sleep is enabled
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent::IsAutoSleepEnabled() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -110,6 +224,13 @@ namespace Ndk
return m_object->IsAutoSleepEnabled();
}
/*!
* \brief Checks whether the entity is currently sleeping
* \return true If it is the case
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline bool PhysicsComponent::IsSleeping() const
{
NazaraAssert(m_object, "Invalid physics object");
@ -117,6 +238,14 @@ namespace Ndk
return m_object->IsSleeping();
}
/*!
* \brief Sets the angular velocity of the physics object
*
* \param angularVelocity Angular velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetAngularVelocity(const Nz::Vector3f& angularVelocity)
{
NazaraAssert(m_object, "Invalid physics object");
@ -124,6 +253,14 @@ namespace Ndk
m_object->SetAngularVelocity(angularVelocity);
}
/*!
* \brief Sets the gravity factor of the physics object
*
* \param gravityFactor Gravity factor of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetGravityFactor(float gravityFactor)
{
NazaraAssert(m_object, "Invalid physics object");
@ -131,6 +268,15 @@ namespace Ndk
m_object->SetGravityFactor(gravityFactor);
}
/*!
* \brief Sets the mass of the physics object
*
* \param mass Mass of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
* \remark Produces a NazaraAssert if the mass is negative
*/
inline void PhysicsComponent::SetMass(float mass)
{
NazaraAssert(m_object, "Invalid physics object");
@ -139,6 +285,14 @@ namespace Ndk
m_object->SetMass(mass);
}
/*!
* \brief Sets the gravity center of the physics object
*
* \param center Gravity center of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetMassCenter(const Nz::Vector3f& center)
{
NazaraAssert(m_object, "Invalid physics object");
@ -146,6 +300,14 @@ namespace Ndk
m_object->SetMassCenter(center);
}
/*!
* \brief Sets the position of the physics object
*
* \param position Position of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetPosition(const Nz::Vector3f& position)
{
NazaraAssert(m_object, "Invalid physics object");
@ -153,6 +315,14 @@ namespace Ndk
m_object->SetPosition(position);
}
/*!
* \brief Sets the rotation of the physics object
*
* \param rotation Rotation of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetRotation(const Nz::Quaternionf& rotation)
{
NazaraAssert(m_object, "Invalid physics object");
@ -160,6 +330,14 @@ namespace Ndk
m_object->SetRotation(rotation);
}
/*!
* \brief Sets the velocity of the physics object
*
* \param velocity Velocity of the object
*
* \remark Produces a NazaraAssert if the physics object is invalid
*/
inline void PhysicsComponent::SetVelocity(const Nz::Vector3f& velocity)
{
NazaraAssert(m_object, "Invalid physics object");
@ -167,6 +345,11 @@ namespace Ndk
m_object->SetVelocity(velocity);
}
/*!
* \brief Gets the underlying physics object
* \return A reference to the physics object
*/
inline Nz::PhysObject& PhysicsComponent::GetPhysObject()
{
return *m_object.get();

View File

@ -7,11 +7,30 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::VelocityComponent
* \brief NDK class that represents the component for velocity
*/
/*!
* \brief Constructs a VelocityComponent object with a velocity
*
* \param velocity Linear velocity
*/
inline VelocityComponent::VelocityComponent(const Nz::Vector3f& velocity) :
linearVelocity(velocity)
{
}
/*!
* \brief Assigns the velocity to this component
* \return A reference to this
*
* \param vel Linear velocity
*/
inline VelocityComponent& VelocityComponent::operator=(const Nz::Vector3f& vel)
{
linearVelocity = vel;

View File

@ -7,41 +7,81 @@
namespace Ndk
{
/*!
* \brief Gets the character size
* \return Height of the character
*/
inline unsigned int Console::GetCharacterSize() const
{
return m_characterSize;
}
/*!
* \brief Gets the entity representing the history of the console
* \return History of the console
*/
inline const EntityHandle& Console::GetHistory() const
{
return m_history;
}
/*!
* \brief Gets the entity representing the background of the console's history
* \return Background history of the console
*/
inline const EntityHandle& Console::GetHistoryBackground() const
{
return m_historyBackground;
}
/*!
* \brief Gets the entity representing the input of the console
* \return Input of the console
*/
inline const EntityHandle& Console::GetInput() const
{
return m_input;
}
/*!
* \brief Gets the entity representing the background of the console's input
* \return Background input of the console
*/
inline const EntityHandle& Console::GetInputBackground() const
{
return m_inputBackground;
}
/*!
* \brief Gets the size of the console
* \return Size (Width, Height) of the console
*/
inline const Nz::Vector2f& Console::GetSize() const
{
return m_size;
}
/*!
* \brief Gets the font used by the console
* \return A reference to the font currenty used
*/
inline const Nz::FontRef& Console::GetTextFont() const
{
return m_defaultFont;
}
/*!
* \brief Checks whether the console is visible
* \return true If it is the case
*/
inline bool Console::IsVisible() const
{
return m_opened;

View File

@ -11,16 +11,29 @@
namespace Ndk
{
/*!
* \brief Adds a component to the entity
* \return A reference to the newly added component
*
* \param args Arguments to create in place the component to add to the entity
*/
template<typename ComponentType, typename... Args>
ComponentType& Entity::AddComponent(Args&&... args)
{
static_assert(std::is_base_of<BaseComponent, ComponentType>::value, "ComponentType is not a component");
// Allocation et affectation du component
// Affectation and return of the component
std::unique_ptr<ComponentType> ptr(new ComponentType(std::forward<Args>(args)...));
return static_cast<ComponentType&>(AddComponent(std::move(ptr)));
}
/*!
* \brief Enables the entity
*
* \param enable Should the entity be enabled
*/
inline void Entity::Enable(bool enable)
{
if (m_enabled != enable)
@ -30,9 +43,17 @@ namespace Ndk
}
}
/*!
* \brief Gets a component in the entity by index
* \return A reference to the component
*
* \param index Index of the component
*
* \remark Produces a NazaraAssert if component is not available in this entity or is invalid
*/
inline BaseComponent& Entity::GetComponent(ComponentIndex index)
{
///DOC: Le component doit être présent
NazaraAssert(HasComponent(index), "This component is not part of the entity");
BaseComponent* component = m_components[index].get();
@ -41,19 +62,33 @@ namespace Ndk
return *component;
}
/*!
* \brief Gets a component in the entity by type
* \return A reference to the component
*
* \remark Produces a NazaraAssert if component is not available in this entity
*/
template<typename ComponentType>
ComponentType& Entity::GetComponent()
{
///DOC: Le component doit être présent
static_assert(std::is_base_of<BaseComponent, ComponentType>::value, "ComponentType is not a component");
ComponentIndex index = GetComponentIndex<ComponentType>();
return static_cast<ComponentType&>(GetComponent(index));
}
/*!
* \brief Gets a component in the entity by index
* \return A constant reference to the component
*
* \param index Index of the component
*
* \remark Produces a NazaraAssert if component is not available in this entity or is invalid
*/
inline const BaseComponent& Entity::GetComponent(ComponentIndex index) const
{
///DOC: Le component doit être présent
NazaraAssert(HasComponent(index), "This component is not part of the entity");
BaseComponent* component = m_components[index].get();
@ -62,41 +97,79 @@ namespace Ndk
return *component;
}
/*!
* \brief Gets a component in the entity by type
* \return A constant reference to the component
*
* \remark Produces a NazaraAssert if component is not available in this entity
*/
template<typename ComponentType>
const ComponentType& Entity::GetComponent() const
{
///DOC: Le component doit être présent
static_assert(std::is_base_of<BaseComponent, ComponentType>::value, "ComponentType is not a component");
ComponentIndex index = GetComponentIndex<ComponentType>();
return static_cast<ComponentType&>(GetComponent(index));
}
/*!
* \brief Gets the bits representing the components in the entiy
* \return A constant reference to the set of component's bits
*/
inline const Nz::Bitset<>& Entity::GetComponentBits() const
{
return m_componentBits;
}
/*!
* \brief Gets the identifier of the entity
* \return Identifier of the entity
*/
inline EntityId Entity::GetId() const
{
return m_id;
}
/*!
* \brief Gets the bits representing the systems in the entiy
* \return A constant reference to the set of system's bits
*/
inline const Nz::Bitset<>& Entity::GetSystemBits() const
{
return m_systemBits;
}
/*!
* \brief Gets the world in which the entity is
* \return Pointer to the world
*/
inline World* Entity::GetWorld() const
{
return m_world;
}
/*!
* \brief Checks whether or not a component is present in the entity by index
* \return true If it is the case
*
* \param index Index of the component
*/
inline bool Entity::HasComponent(ComponentIndex index) const
{
return m_componentBits.UnboundedTest(index);
}
/*!
* \brief Checks whether or not a component is present in the entity by type
* \return true If it is the case
*/
template<typename ComponentType>
bool Entity::HasComponent() const
{
@ -106,16 +179,54 @@ namespace Ndk
return HasComponent(index);
}
/*!
* \brief Checks whether or not the entity is enabled
* \return true If it is the case
*/
inline bool Entity::IsEnabled() const
{
return m_enabled;
}
/*!
* \brief Checks whether or not the entity is valid
* \return true If it is the case
*/
inline bool Entity::IsValid() const
{
return m_valid;
}
/*!
* \brief Removes every components
*/
inline void Entity::RemoveAllComponents()
{
m_removedComponentBits = m_componentBits;
Invalidate();
}
/*!
* \brief Removes a component in the entity by index
*
* \param index Index of the component
*/
inline void Entity::RemoveComponent(ComponentIndex index)
{
m_removedComponentBits.UnboundedSet(index);
Invalidate();
}
/*!
* \brief Removes a component in the entity by type
*/
template<typename ComponentType>
void Entity::RemoveComponent()
{
@ -125,19 +236,10 @@ namespace Ndk
RemoveComponent(index);
}
inline void Entity::RemoveAllComponents()
{
m_removedComponentBits = m_componentBits;
Invalidate();
}
inline void Entity::RemoveComponent(ComponentIndex index)
{
m_removedComponentBits.UnboundedSet(index);
Invalidate();
}
/*!
* \brief Gives a string representation
* \return A string representation of the object: "Entity(GetId())"
*/
inline Nz::String Entity::ToString() const
{
@ -145,16 +247,35 @@ namespace Ndk
return ss << "Entity(" << GetId() << ')';
}
/*!
* \brief Gets the bits representing the removed components in the entiy
* \return A constant reference to the set of remove component's bits
*/
inline Nz::Bitset<>& Entity::GetRemovedComponentBits()
{
return m_removedComponentBits;
}
/*!
* \brief Registers a system for the entity
*
* \param index Index of the system
*/
inline void Entity::RegisterSystem(SystemIndex index)
{
m_systemBits.UnboundedSet(index);
}
/*!
* \brief Sets the world of the entity
*
* \param world World in which the entity will be
*
* \remark Produces a NazaraAssert if world is invalid
*/
inline void Entity::SetWorld(World* world) noexcept
{
NazaraAssert(world, "An entity must be attached to a world at any time");
@ -162,6 +283,12 @@ namespace Ndk
m_world = world;
}
/*!
* \brief Unregisters a system for the entity
*
* \param index Index of the system
*/
inline void Entity::UnregisterSystem(SystemIndex index)
{
m_systemBits.UnboundedReset(index);
@ -173,10 +300,16 @@ namespace std
template<>
struct hash<Ndk::EntityHandle>
{
/*!
* \brief Specialisation of std to hash
* \return Result of the hash
*
* \param handle Entity to hash
*/
size_t operator()(const Ndk::EntityHandle& handle) const
{
// Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée
// pour cette raison, nous devons hasher l'ID de l'entité (qui reste constante)
// Hash the pointer will work until the entity is updated and moved
// so, we have to hash the ID of the entity (which is constant)
Ndk::EntityId id = (handle.IsValid()) ? handle->GetId() : std::numeric_limits<Ndk::EntityId>::max();
return hash<Ndk::EntityId>()(id);

View File

@ -7,22 +7,54 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::EntityList
* \brief NDK class that represents a set of entities to help performing batch operations
*/
/*!
* \brief Clears the set from every entities
*/
inline void EntityList::Clear()
{
m_entities.clear();
m_entityBits.Clear();
}
/*!
* \brief Checks whether or not the set contains the entity
* \return true If it is the case
*
* \param entity Pointer to the entity
*/
inline bool EntityList::Has(const Entity* entity)
{
return entity && entity->IsValid() && Has(entity->GetId());
}
/*!
* \brief Checks whether or not the set contains the entity by id
* \return true If it is the case
*
* \param id Identifier of the entity
*/
inline bool EntityList::Has(EntityId entity)
{
return m_entityBits.UnboundedTest(entity);
}
/*!
* \brief Inserts the entity into the set
*
* \param entity Pointer to the entity
*
* \remark If entity is already contained, no action is performed
*/
inline void EntityList::Insert(Entity* entity)
{
if (!Has(entity))
@ -32,6 +64,14 @@ namespace Ndk
}
}
/*!
* \brief Removes the entity from the set
*
* \param entity Pointer to the entity
*
* \remark If entity is not contained, no action is performed
*/
inline void EntityList::Remove(Entity* entity)
{
if (Has(entity))
@ -40,7 +80,7 @@ namespace Ndk
NazaraAssert(it != m_entities.end(), "Entity should be part of the vector");
std::swap(*it, m_entities.back());
m_entities.pop_back(); // On le sort du vector
m_entities.pop_back(); // We get it out of the vector
m_entityBits.UnboundedSet(entity->GetId(), false);
}
}

View File

@ -8,17 +8,41 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::EntityOwner
* \brief NDK class that represents the owner of the entity and so its lifetime
*/
/*!
* \brief Constructs a EntityOwner object
*
* \param entity Entity to own
*/
inline EntityOwner::EntityOwner(Entity* entity) :
EntityOwner()
{
Reset(entity);
}
/*!
* \brief Destructs the object and calls Reset
*
* \see Reset
*/
inline EntityOwner::~EntityOwner()
{
Reset(nullptr);
}
/*!
* \brief Resets the ownership of the entity, previous is killed
*
* \param entity Entity to own
*/
inline void EntityOwner::Reset(Entity* entity)
{
if (m_object)
@ -27,12 +51,24 @@ namespace Ndk
EntityHandle::Reset(entity);
}
/*!
* \brief Resets the ownership of the entity by move semantic
*
* \param handle EntityOwner to move into this
*/
inline void EntityOwner::Reset(EntityOwner&& handle)
{
Reset(handle.GetObject());
handle.m_object = nullptr;
}
/*!
* \brief Resets the ownership of the entity to the affected one
*
* \param entity Entity to own
*/
inline EntityOwner& EntityOwner::operator=(Entity* entity)
{
Reset(entity);

View File

@ -26,6 +26,11 @@
namespace Ndk
{
/*!
* \brief Gets the internal binding for Lua
* \return A pointer to the binding
*/
inline LuaBinding* LuaAPI::GetBinding()
{
return s_binding;
@ -34,6 +39,15 @@ namespace Ndk
namespace Nz
{
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param color Resulting color
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Color* color, TypeTag<Color>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -46,6 +60,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param angles Resulting euler angles
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag<EulerAnglesd>)
{
switch (instance.GetType(index))
@ -66,6 +89,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param angles Resulting euler angles
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesf* angles, TypeTag<EulerAnglesf>)
{
EulerAnglesd anglesDouble;
@ -75,6 +107,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param fontRef Resulting reference to a font
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontRef* fontRef, TypeTag<FontRef>)
{
*fontRef = *static_cast<FontRef*>(instance.CheckUserdata(index, "Font"));
@ -82,6 +123,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a font
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag<FontParams>)
{
NazaraUnused(params);
@ -93,6 +143,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a mesh
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MeshParams* params, TypeTag<MeshParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -106,6 +165,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param rect Resulting rectangle
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectd* rect, TypeTag<Rectd>)
{
instance.CheckType(index, LuaType_Table);
@ -118,6 +186,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param rect Resulting rectangle
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectf* rect, TypeTag<Rectf>)
{
Rectd rectDouble;
@ -127,6 +204,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param rect Resulting rectangle
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectui* rect, TypeTag<Rectui>)
{
Rectd rectDouble;
@ -136,6 +222,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param quat Resulting quaternion
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaterniond* quat, TypeTag<Quaterniond>)
{
switch (instance.GetType(index))
@ -156,6 +251,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param quat Resulting quaternion
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaternionf* quat, TypeTag<Quaternionf>)
{
Quaterniond quatDouble;
@ -165,6 +269,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param address Resulting IP address
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, IpAddress* address, TypeTag<IpAddress>)
{
switch (instance.GetType(index))
@ -179,6 +292,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector2D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2d* vec, TypeTag<Vector2d>)
{
switch (instance.GetType(index))
@ -200,6 +322,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector2D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2f* vec, TypeTag<Vector2f>)
{
Vector2d vecDouble;
@ -209,6 +340,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector2D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2ui* vec, TypeTag<Vector2ui>)
{
Vector2d vecDouble;
@ -218,6 +358,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector3D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3d* vec, TypeTag<Vector3d>)
{
switch (instance.GetType(index))
@ -239,6 +388,15 @@ namespace Nz
}
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector3D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3f* vec, TypeTag<Vector3f>)
{
Vector3d vecDouble;
@ -248,6 +406,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param vec Resulting vector3D
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3ui* vec, TypeTag<Vector3ui>)
{
Vector3d vecDouble;
@ -257,6 +424,15 @@ namespace Nz
return ret;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param handle Resulting entity
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag<Ndk::EntityHandle>)
{
*handle = *static_cast<Ndk::EntityHandle*>(instance.CheckUserdata(index, "Entity"));
@ -264,6 +440,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param handle Resulting world
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag<Ndk::WorldHandle>)
{
*handle = *static_cast<Ndk::WorldHandle*>(instance.CheckUserdata(index, "World"));
@ -272,6 +457,16 @@ namespace Nz
}
#ifndef NDK_SERVER
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param renderable Resulting reference to a instanced renderable
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, InstancedRenderableRef* renderable, TypeTag<InstancedRenderableRef>)
{
if (instance.IsOfType(index, "InstancedRenderable"))
@ -281,6 +476,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a material
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialParams* params, TypeTag<MaterialParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -295,6 +499,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a model
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ModelParameters* params, TypeTag<ModelParameters>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -307,6 +520,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a music
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MusicParams* params, TypeTag<MusicParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -316,6 +538,15 @@ namespace Nz
return 1;
}
/*!
* \brief Queries arguments for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param index Index type
* \param params Resulting parameters for a sound buffer
*/
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag<SoundBufferParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
@ -324,9 +555,16 @@ namespace Nz
return 1;
}
#endif
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting euler angles
*/
inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesd&& val, TypeTag<EulerAnglesd>)
{
@ -334,18 +572,42 @@ namespace Nz
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting euler angles
*/
inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesf&& val, TypeTag<EulerAnglesf>)
{
instance.PushInstance<EulerAnglesd>("EulerAngles", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting reference to a font
*/
inline int LuaImplReplyVal(const LuaInstance& instance, FontRef&& val, TypeTag<FontRef>)
{
instance.PushInstance<FontRef>("Font", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting size information for a font
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Font::SizeInfo&& val, TypeTag<Font::SizeInfo>)
{
instance.PushTable();
@ -357,114 +619,266 @@ namespace Nz
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting quaternion
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Quaterniond&& val, TypeTag<Quaterniond>)
{
instance.PushInstance<Quaterniond>("Quaternion", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting quaternion
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Quaternionf&& val, TypeTag<Quaternionf>)
{
instance.PushInstance<Quaterniond>("Quaternion", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting IP address
*/
inline int LuaImplReplyVal(const LuaInstance& instance, IpAddress&& val, TypeTag<IpAddress>)
{
instance.PushInstance<IpAddress>("IpAddress", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting rectangle
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Rectd&& val, TypeTag<Rectf>)
{
instance.PushInstance<Rectd>("Rect", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting rectangle
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Rectf&& val, TypeTag<Rectf>)
{
instance.PushInstance<Rectd>("Rect", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting rectangle
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Rectui&& val, TypeTag<Rectui>)
{
instance.PushInstance<Rectd>("Rect", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector2D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2d&& val, TypeTag<Vector2d>)
{
instance.PushInstance<Vector2d>("Vector2", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector2D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2f&& val, TypeTag<Vector2f>)
{
instance.PushInstance<Vector2d>("Vector2", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector2D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2ui&& val, TypeTag<Vector2ui>)
{
instance.PushInstance<Vector2d>("Vector2", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector3D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d&& val, TypeTag<Vector3d>)
{
instance.PushInstance<Vector3d>("Vector3", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector3D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3f&& val, TypeTag<Vector3f>)
{
instance.PushInstance<Vector3d>("Vector3", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting vector3D
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3ui&& val, TypeTag<Vector3ui>)
{
instance.PushInstance<Vector3d>("Vector3", val);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting entity
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Entity* ptr, TypeTag<Ndk::Entity*>)
{
instance.PushInstance<Ndk::EntityHandle>("Entity", ptr);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting application
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Application* ptr, TypeTag<Ndk::Application*>)
{
instance.PushInstance<Ndk::Application*>("Application", ptr);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting entity
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle&& handle, TypeTag<Ndk::EntityHandle>)
{
instance.PushInstance<Ndk::EntityHandle>("Entity", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting node component
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::NodeComponentHandle&& handle, TypeTag<Ndk::NodeComponentHandle>)
{
instance.PushInstance<Ndk::NodeComponentHandle>("NodeComponent", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting velocity component
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::VelocityComponentHandle&& handle, TypeTag<Ndk::VelocityComponentHandle>)
{
instance.PushInstance<Ndk::VelocityComponentHandle>("VelocityComponent", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting world
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag<Ndk::World*>)
{
instance.PushInstance<Ndk::WorldHandle>("World", ptr);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param ptr Resulting world
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::WorldHandle&& handle, TypeTag<Ndk::WorldHandle>)
{
instance.PushInstance<Ndk::WorldHandle>("World", handle);
@ -472,22 +886,49 @@ namespace Nz
}
#ifndef NDK_SERVER
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting console
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::ConsoleHandle&& handle, TypeTag<Ndk::ConsoleHandle>)
{
instance.PushInstance<Ndk::ConsoleHandle>("Console", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param handle Resulting graphics component
*/
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle&& handle, TypeTag<Ndk::GraphicsComponentHandle>)
{
instance.PushInstance<Ndk::GraphicsComponentHandle>("GraphicsComponent", handle);
return 1;
}
/*!
* \brief Replies by value for Lua
* \return 1 in case of success
*
* \param instance Lua instance to interact with
* \param val Resulting sound buffer
*/
inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag<const SoundBuffer*>)
{
instance.PushInstance<SoundBufferConstRef>("SoundBuffer", val);
return 1;
}
#endif
}

View File

@ -6,6 +6,14 @@
namespace Ndk
{
/*!
* \brief Binds a component to a name
*
* \param name Name used to retrieve the component
*
* \remark Produces a NazaraAssert if name is empty
*/
template<typename T>
void LuaBinding::BindComponent(const Nz::String& name)
{
@ -24,6 +32,16 @@ namespace Ndk
m_componentBindingByName[name] = T::componentIndex;
}
/*!
* \brief Adds a component to an entity
* \return 1 in case of success
*
* \param instance Lua instance that will interact with the component
* \param handle Entity which component will be added to
*
* \remark T must be a subtype of BaseComponent
*/
template<typename T>
int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle)
{
@ -34,6 +52,16 @@ namespace Ndk
return 1;
}
/*!
* \brief Pushes a component
* \return 1 in case of success
*
* \param instance Lua instance that will interact with the component
* \param component Component that will be pushed
*
* \remark T must be a subtype of BaseComponent
*/
template<typename T>
int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component)
{

View File

@ -27,11 +27,11 @@
#include <Nazara/Prerequesites.hpp>
// Version du SDK
// Version of SDK
#define NDK_VERSION_MAJOR 0
#define NDK_VERSION_MINOR 1
// Importation/Exportation de l'API
// Importation/Exportation of the API
#if defined(NAZARA_PLATFORM_WINDOWS)
#if !defined(NDK_STATIC)
#ifdef NDK_BUILD
@ -49,7 +49,7 @@
#define NDK_API
#endif
#else
// À commenter pour tenter quand même une compilation
// To comment to force a compilation
#error This operating system is not fully supported by the Nazara Development Kit
#define NDK_API

View File

@ -4,6 +4,11 @@
namespace Ndk
{
/*!
* \brief Checks whether the module is initialized
* \return true if module is initialized
*/
inline bool Sdk::IsInitialized()
{
return s_referenceCounter != 0;

View File

@ -8,6 +8,21 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::StateMachine
* \brief NDK class that represents a state machine, to represent the multiple states of your program
*/
/*!
* \brief Constructs a StateMachine object with an original state
*
* \param originalState State which is the entry point of the application
*
* \remark Calls "Enter" on the state
* \remark Produces a NazaraAssert if nullptr is given
*/
inline StateMachine::StateMachine(std::shared_ptr<State> originalState) :
m_currentState(std::move(originalState))
{
@ -15,22 +30,45 @@ namespace Ndk
m_currentState->Enter(*this);
}
/*!
* \brief Destructs the object
*
* \remark Calls "Leave" on the state
*/
inline StateMachine::~StateMachine()
{
m_currentState->Leave(*this);
}
/*!
* \brief Changes the current state of the machine
*
* \param state Next state to represent
*/
inline void StateMachine::ChangeState(std::shared_ptr<State> state)
{
m_nextState = std::move(state);
}
/*!
* \brief Gets the current state of the machine
* \return A constant reference to the state
*/
inline const std::shared_ptr<State>& StateMachine::GetCurrentState() const
{
return m_currentState;
}
/*!
* \brief Updates the state
* \return True if update is successful
*
* \param elapsedTime Delta time used for the update
*/
inline bool StateMachine::Update(float elapsedTime)
{
if (m_nextState)

View File

@ -11,7 +11,7 @@
namespace Ndk
{
template<typename ComponentType>
template<typename SystemType>
class System : public BaseSystem
{
public:
@ -20,7 +20,7 @@ namespace Ndk
System(System&&) = default;
virtual ~System();
BaseSystem* Clone() const override;
std::unique_ptr<BaseSystem> Clone() const override;
System& operator=(const System&) = delete;
System& operator=(System&&) = default;

View File

@ -7,6 +7,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::System<SystemType>
* \brief NDK class that represents a system which interacts on a world
*
* \remark This class is meant to be derived as CRTP: "System<Subtype>"
*/
/*!
* \brief Constructs a System object by default
*/
template<typename SystemType>
System<SystemType>::System() :
BaseSystem(GetSystemIndex<SystemType>())
@ -16,15 +28,26 @@ namespace Ndk
template<typename SystemType>
System<SystemType>::~System() = default;
/*!
* \brief Clones the system
* \return The clone newly created
*
* \remark The system to clone should be trivially copy constructible
*/
template<typename SystemType>
BaseSystem* System<SystemType>::Clone() const
std::unique_ptr<BaseSystem> System<SystemType>::Clone() const
{
///FIXME: Pas encore supporté par GCC (4.9.2)
///FIXME: Not fully supported in GCC (4.9.2)
//static_assert(std::is_trivially_copy_constructible<SystemType>::value, "SystemType should be copy-constructible");
return new SystemType(static_cast<const SystemType&>(*this));
return std::make_unique<SystemType>(static_cast<const SystemType&>(*this));
}
/*!
* \brief Registers the system by assigning it an index
*/
template<typename SystemType>
SystemIndex System<SystemType>::RegisterSystem()
{

View File

@ -4,11 +4,21 @@
namespace Ndk
{
/*!
* \brief Gets the physical world
* \return A reference to the physical world
*/
inline Nz::PhysWorld& PhysicsSystem::GetWorld()
{
return m_world;
}
/*!
* \brief Gets the physical world
* \return A constant reference to the physical world
*/
inline const Nz::PhysWorld& PhysicsSystem::GetWorld() const
{
return m_world;

View File

@ -4,58 +4,119 @@
namespace Ndk
{
/*!
* \brief Constructs a RenderSystem object by copy semantic
*
* \param renderSystem RenderSystem to copy
*/
inline RenderSystem::RenderSystem(const RenderSystem& renderSystem) :
System(renderSystem)
{
}
/*!
* \brief Changes the render technique used for the system
* \return A reference to the render technique type
*/
template<typename T>
inline T& RenderSystem::ChangeRenderTechnique()
{
static_assert(std::is_base_of<Nz::AbstractRenderTechnique, T>::value, "RenderTechnique is not a subtype of AbstractRenderTechnique");
return static_cast<T&>(ChangeRenderTechnique(std::make_unique<T>()));
}
/*!
* \brief Changes the render technique used for the system
* \return A reference to the abstract render technique
*
* \param renderTechnique Render technique to use
*/
inline Nz::AbstractRenderTechnique& RenderSystem::ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique)
{
m_renderTechnique = std::move(renderTechnique);
return *m_renderTechnique.get();
}
/*!
* \brief Gets the background used for rendering
* \return A reference to the background
*/
inline const Nz::BackgroundRef& RenderSystem::GetDefaultBackground() const
{
return m_background;
}
/*!
* \brief Gets the coordinates matrix used for rendering
* \return A constant reference to the matrix of coordinates
*/
inline const Nz::Matrix4f& RenderSystem::GetCoordinateSystemMatrix() const
{
return m_coordinateSystemMatrix;
}
/*!
* \brief Gets the "forward" global direction
* \return The forward direction, by default, it's -UnitZ() (Right hand coordinates)
*/
inline Nz::Vector3f RenderSystem::GetGlobalForward() const
{
return Nz::Vector3f(-m_coordinateSystemMatrix.m13, -m_coordinateSystemMatrix.m23, -m_coordinateSystemMatrix.m33);
}
/*!
* \brief Gets the "right" global direction
* \return The right direction, by default, it's UnitX() (Right hand coordinates)
*/
inline Nz::Vector3f RenderSystem::GetGlobalRight() const
{
return Nz::Vector3f(m_coordinateSystemMatrix.m11, m_coordinateSystemMatrix.m21, m_coordinateSystemMatrix.m31);
}
/*!
* \brief Gets the "up" global direction
* \return The up direction, by default, it's UnitY() (Right hand coordinates)
*/
inline Nz::Vector3f RenderSystem::GetGlobalUp() const
{
return Nz::Vector3f(m_coordinateSystemMatrix.m12, m_coordinateSystemMatrix.m22, m_coordinateSystemMatrix.m32);
}
/*!
* \brief Gets the render technique used for rendering
* \return A reference to the abstract render technique being used
*/
inline Nz::AbstractRenderTechnique& RenderSystem::GetRenderTechnique() const
{
return *m_renderTechnique.get();
}
/*!
* \brief Sets the background used for rendering
*
* \param background A reference to the background
*/
inline void RenderSystem::SetDefaultBackground(Nz::BackgroundRef background)
{
m_background = std::move(background);
}
/*!
* \brief Sets the "forward" global direction
*
* \param direction The new forward direction
*/
inline void RenderSystem::SetGlobalForward(const Nz::Vector3f& direction)
{
m_coordinateSystemMatrix.m13 = -direction.x;
@ -65,6 +126,12 @@ namespace Ndk
InvalidateCoordinateSystem();
}
/*!
* \brief Sets the "right" global direction
*
* \param direction The new right direction
*/
inline void RenderSystem::SetGlobalRight(const Nz::Vector3f& direction)
{
m_coordinateSystemMatrix.m11 = direction.x;
@ -74,6 +141,12 @@ namespace Ndk
InvalidateCoordinateSystem();
}
/*!
* \brief Sets the "up" global direction
*
* \param direction The new up direction
*/
inline void RenderSystem::SetGlobalUp(const Nz::Vector3f& direction)
{
m_coordinateSystemMatrix.m12 = direction.x;
@ -83,6 +156,10 @@ namespace Ndk
InvalidateCoordinateSystem();
}
/*!
* \brief Invalidates the matrix of coordinates for the system
*/
inline void RenderSystem::InvalidateCoordinateSystem()
{
m_coordinateSystemInvalidated = true;

View File

@ -43,7 +43,6 @@ namespace Ndk
inline EntityList CreateEntities(unsigned int count);
void Clear() noexcept;
const EntityHandle& CloneEntity(EntityId id);
const EntityHandle& GetEntity(EntityId id);

View File

@ -7,47 +7,80 @@
namespace Ndk
{
/*!
* \brief Constructs a World object
*
* \param addDefaultSystems Should default provided systems be used
*/
inline World::World(bool addDefaultSystems)
{
if (addDefaultSystems)
AddDefaultSystems();
}
/*!
* \brief Constructs a World object by move semantic
*
* \param world World to move into this
*/
inline World::World(World&& world) noexcept :
HandledObject(std::move(world))
{
operator=(std::move(world));
}
/*!
* \brief Adds a system to the world
* \return A reference to the newly created system
*
* \param system System to add to the world
*/
inline BaseSystem& World::AddSystem(std::unique_ptr<BaseSystem>&& system)
{
NazaraAssert(system, "System must be valid");
SystemIndex index = system->GetIndex();
// Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component
// We must ensure that the vector is big enough to hold the new system
if (index >= m_systems.size())
m_systems.resize(index + 1);
// Affectation et retour du système
// Affectation and return of system
m_systems[index] = std::move(system);
m_systems[index]->SetWorld(this);
Invalidate(); // On force une mise à jour de toutes les entités
Invalidate(); // We force an update for every entities
return *m_systems[index].get();
}
/*!
* \brief Adds a system to the world
* \return A reference to the newly created system
*
* \param args Arguments used to create the system
*/
template<typename SystemType, typename... Args>
SystemType& World::AddSystem(Args&&... args)
{
static_assert(std::is_base_of<BaseSystem, SystemType>::value, "SystemType is not a component");
// Allocation et affectation du component
// Allocation and affectation of the system
std::unique_ptr<SystemType> ptr(new SystemType(std::forward<Args>(args)...));
return static_cast<SystemType&>(AddSystem(std::move(ptr)));
}
/*!
* \brief Creates multiple entities in the world
* \return The set of entities created
*
* \param count Number of entities to create
*/
inline World::EntityList World::CreateEntities(unsigned int count)
{
EntityList list;
@ -59,14 +92,27 @@ namespace Ndk
return list;
}
/*!
* \brief Gets every entities in the world
* \return A constant reference to the entities
*/
inline const World::EntityList& World::GetEntities()
{
return m_aliveEntities;
}
/*!
* \brief Gets a system in the world by index
* \return A reference to the system
*
* \param index Index of the system
*
* \remark Produces a NazaraAssert if system is not available in this world
*/
inline BaseSystem& World::GetSystem(SystemIndex index)
{
///DOC: Le système doit être présent
NazaraAssert(HasSystem(index), "This system is not part of the world");
BaseSystem* system = m_systems[index].get();
@ -75,21 +121,39 @@ namespace Ndk
return *system;
}
/*!
* \brief Gets a system in the world by type
* \return A reference to the system
*
* \remark Produces a NazaraAssert if system is not available in this world
*/
template<typename SystemType>
SystemType& World::GetSystem()
{
///DOC: Le système doit être présent
static_assert(std::is_base_of<BaseSystem, SystemType>::value, "SystemType is not a system");
SystemIndex index = GetSystemIndex<SystemType>();
return static_cast<SystemType&>(GetSystem(index));
}
/*!
* \brief Checks whether or not a system is present in the world by index
* \return true If it is the case
*
* \param index Index of the system
*/
inline bool World::HasSystem(SystemIndex index) const
{
return index < m_systems.size() && m_systems[index];
}
/*!
* \brief Checks whether or not a system is present in the world by type
* \return true If it is the case
*/
template<typename SystemType>
bool World::HasSystem() const
{
@ -99,34 +163,69 @@ namespace Ndk
return HasSystem(index);
}
/*!
* \brief Kills a set of entities
*
* \param list Set of entities to kill
*/
inline void World::KillEntities(const EntityList& list)
{
for (const EntityHandle& entity : list)
KillEntity(entity);
}
/*!
* \brief Checks whether or not an entity is valid
* \return true If it is the case
*
* \param entity Pointer to the entity
*/
inline bool World::IsEntityValid(const Entity* entity) const
{
return entity && entity->GetWorld() == this && IsEntityIdValid(entity->GetId());
}
/*!
* \brief Checks whether or not an entity is valid
* \return true If it is the case
*
* \param id Identifier of the entity
*/
inline bool World::IsEntityIdValid(EntityId id) const
{
return id < m_entities.size() && m_entities[id].entity.IsValid();
}
/*!
* \brief Removes each system from the world
*/
inline void World::RemoveAllSystems()
{
m_systems.clear();
}
/*!
* \brief Removes a system from the world by index
*
* \param index Index of the system
*
* \remark No change is done if system is not present
*/
inline void World::RemoveSystem(SystemIndex index)
{
///DOC: N'a aucun effet si le système n'est pas présent
if (HasSystem(index))
m_systems[index].reset();
}
/*!
* \brief Removes a system from the world by type
*/
template<typename SystemType>
void World::RemoveSystem()
{
@ -136,6 +235,12 @@ namespace Ndk
RemoveSystem(index);
}
/*!
* \brief Updates the world
*
* \param elapsedTime Delta time used for the update
*/
inline void World::Update(float elapsedTime)
{
Update(); //< Update entities
@ -148,17 +253,32 @@ namespace Ndk
}
}
/*!
* \brief Invalidates each entity in the world
*/
inline void World::Invalidate()
{
m_dirtyEntities.Resize(m_entities.size(), false);
m_dirtyEntities.Set(true); // Activation de tous les bits
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);
}
/*!
* \brief Moves a world into another world object
* \return A reference to the object
*/
inline World& World::operator=(World&& world) noexcept
{
m_aliveEntities = std::move(world.m_aliveEntities);

View File

@ -6,6 +6,16 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::Application
* \brief NDK class that represents the application, it offers a set of tools to ease the development
*/
/*!
* \brief Runs the application by updating worlds, taking care about windows, ...
*/
bool Application::Run()
{
#ifndef NDK_SERVER

View File

@ -6,22 +6,50 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::BaseComponent
* \brief NDK class that represents the common base of all components
*
* \remark This class is meant to be purely abstract, for type erasure
*/
BaseComponent::~BaseComponent() = default;
/*!
* \brief Operation to perform when component is attached to an entity
*/
void BaseComponent::OnAttached()
{
}
/*!
* \brief Operation to perform when component is attached to this component
*
* \param component Component being attached
*/
void BaseComponent::OnComponentAttached(BaseComponent& component)
{
NazaraUnused(component);
}
/*!
* \brief Operation to perform when component is detached from this component
*
* \param component Component being detached
*/
void BaseComponent::OnComponentDetached(BaseComponent& component)
{
NazaraUnused(component);
}
/*!
* \brief Operation to perform when component is detached from an entity
*/
void BaseComponent::OnDetached()
{
}

View File

@ -6,12 +6,31 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::BaseSystem
* \brief NDK class that represents the common base of all systems
*
* \remark This class is meant to be purely abstract, for type erasure
*/
/*!
* \brief Destructs the object and unregisters it-self on every entities
*/
BaseSystem::~BaseSystem()
{
for (const EntityHandle& entity : m_entities)
entity->UnregisterSystem(m_systemIndex);
}
/*!
* \brief Checks whether the key of the entity matches the lock of the system
* \return true If it is the case
*
* \param Pointer to the entity
*/
bool BaseSystem::Filters(const Entity* entity) const
{
if (!entity)
@ -21,13 +40,13 @@ namespace Ndk
m_filterResult.PerformsAND(m_requiredComponents, components);
if (m_filterResult != m_requiredComponents)
return false; // Au moins un component requis n'est pas présent
return false; // At least one required component is not available
m_filterResult.PerformsAND(m_excludedComponents, components);
if (m_filterResult.TestAny())
return false; // Au moins un component exclu est présent
return false; // At least one excluded component is available
// Si nous avons une liste de composants nécessaires
// If we have a list of needed components
if (m_requiredAnyComponents.TestAny())
{
if (!m_requiredAnyComponents.Intersects(components))
@ -37,16 +56,35 @@ namespace Ndk
return true;
}
/*!
* \brief Operation to perform when entity is added to the system
*
* \param Pointer to the entity
*/
void BaseSystem::OnEntityAdded(Entity* entity)
{
NazaraUnused(entity);
}
/*!
* \brief Operation to perform when entity is removed to the system
*
* \param Pointer to the entity
*/
void BaseSystem::OnEntityRemoved(Entity* entity)
{
NazaraUnused(entity);
}
/*!
* \brief Operation to perform when entity is validated for the system
*
* \param entity Pointer to the entity
* \param justAdded Is the entity newly added
*/
void BaseSystem::OnEntityValidation(Entity* entity, bool justAdded)
{
NazaraUnused(entity);

View File

@ -9,6 +9,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::CameraComponent
* \brief NDK class that represents the component for camera
*/
/*!
* \brief Applys the view of the camera
*
* \remark Produces a NazaraAssert if the camera has no target
*/
void CameraComponent::ApplyView() const
{
NazaraAssert(m_target, "CameraComponent has no target");
@ -23,6 +35,12 @@ namespace Ndk
Nz::Renderer::SetViewport(m_viewport);
}
/*!
* \brief Gets the eye position of the camera
*
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
*/
Nz::Vector3f CameraComponent::GetEyePosition() const
{
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
@ -30,6 +48,12 @@ namespace Ndk
return m_entity->GetComponent<NodeComponent>().GetPosition();
}
/*!
* \brief Gets the forward direction of the camera
*
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
*/
Nz::Vector3f CameraComponent::GetForward() const
{
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
@ -37,6 +61,12 @@ namespace Ndk
return m_entity->GetComponent<NodeComponent>().GetForward();
}
/*!
* \brief Sets the layer of the camera in case of multiples fields
*
* \param layer Layer of the camera
*/
void CameraComponent::SetLayer(unsigned int layer)
{
m_layer = layer;
@ -44,6 +74,10 @@ namespace Ndk
m_entity->Invalidate(); // Invalidate the entity to make it passes through RenderSystem validation
}
/*!
* \brief Operation to perform when component is attached to an entity
*/
void CameraComponent::OnAttached()
{
if (m_entity->HasComponent<NodeComponent>())
@ -52,6 +86,12 @@ namespace Ndk
InvalidateViewMatrix();
}
/*!
* \brief Operation to perform when component is attached to this component
*
* \param component Component being attached
*/
void CameraComponent::OnComponentAttached(BaseComponent& component)
{
if (IsComponent<NodeComponent>(component))
@ -63,6 +103,12 @@ namespace Ndk
}
}
/*!
* \brief Operation to perform when component is detached from this component
*
* \param component Component being detached
*/
void CameraComponent::OnComponentDetached(BaseComponent& component)
{
if (IsComponent<NodeComponent>(component))
@ -73,6 +119,10 @@ namespace Ndk
}
}
/*!
* \brief Operation to perform when component is detached from an entity
*/
void CameraComponent::OnDetached()
{
m_nodeInvalidationSlot.Disconnect();
@ -80,6 +130,12 @@ namespace Ndk
InvalidateViewMatrix();
}
/*!
* \brief Operation to perform when the node is invalidated
*
* \param node Pointer to the node
*/
void CameraComponent::OnNodeInvalidated(const Nz::Node* node)
{
NazaraUnused(node);
@ -88,6 +144,12 @@ namespace Ndk
InvalidateViewMatrix();
}
/*!
* \brief Operation to perform when the render target is released
*
* \param renderTarget Pointer to the RenderTarget
*/
void CameraComponent::OnRenderTargetRelease(const Nz::RenderTarget* renderTarget)
{
if (renderTarget == m_target)
@ -96,6 +158,12 @@ namespace Ndk
NazaraInternalError("Not listening to " + Nz::String::Pointer(renderTarget));
}
/*!
* \brief Operation to perform when the render target has its size changed
*
* \param renderTarget Pointer to the RenderTarget
*/
void CameraComponent::OnRenderTargetSizeChange(const Nz::RenderTarget* renderTarget)
{
if (renderTarget == m_target)
@ -104,6 +172,10 @@ namespace Ndk
NazaraInternalError("Not listening to " + Nz::String::Pointer(renderTarget));
}
/*!
* \brief Updates the frustum of the camera
*/
void CameraComponent::UpdateFrustum() const
{
EnsureProjectionMatrixUpdate();
@ -114,6 +186,10 @@ namespace Ndk
m_frustumUpdated = true;
}
/*!
* \brief Updates the project matrix of the camera
*/
void CameraComponent::UpdateProjectionMatrix() const
{
switch (m_projectionType)
@ -139,6 +215,12 @@ namespace Ndk
m_projectionMatrixUpdated = true;
}
/*!
* \brief Updates the view matrix of the camera
*
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
*/
void CameraComponent::UpdateViewMatrix() const
{
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
@ -150,6 +232,12 @@ namespace Ndk
m_viewMatrixUpdated = true;
}
/*!
* \brief Updates the view port of the camera
*
* \remark Produces a NazaraAssert if entity has no target
*/
void CameraComponent::UpdateViewport() const
{
NazaraAssert(m_target, "CameraComponent has no target");

View File

@ -11,13 +11,27 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::CollisionComponent
* \brief NDK class that represents the component for collision (meant for static objects)
*/
/*!
* \brief Sets geometry for the entity
*
* \param geom Geometry used for collisions
*
* \remark Produces a NazaraAssert if the entity has no physics component and has no static body
*/
void CollisionComponent::SetGeom(Nz::PhysGeomRef geom)
{
m_geom = std::move(geom);
if (m_entity->HasComponent<PhysicsComponent>())
{
// On met à jour la géométrie du PhysObject associé au PhysicsComponent
// We update the geometry of the PhysiscsObject linked to the PhysicsComponent
PhysicsComponent& physComponent = m_entity->GetComponent<PhysicsComponent>();
physComponent.GetPhysObject().SetGeom(m_geom);
}
@ -28,6 +42,13 @@ namespace Ndk
}
}
/*!
* \brief Initializes the static body
*
* \remark Produces a NazaraAssert if entity is invalid
* \remark Produces a NazaraAssert if entity is not linked to a world, or the world has no physics system
*/
void CollisionComponent::InitializeStaticBody()
{
NazaraAssert(m_entity, "Invalid entity");
@ -41,24 +62,44 @@ namespace Ndk
m_staticBody->EnableAutoSleep(false);
}
/*!
* \brief Operation to perform when component is attached to an entity
*/
void CollisionComponent::OnAttached()
{
if (!m_entity->HasComponent<PhysicsComponent>())
InitializeStaticBody();
}
/*!
* \brief Operation to perform when component is attached to this component
*
* \param component Component being attached
*/
void CollisionComponent::OnComponentAttached(BaseComponent& component)
{
if (IsComponent<PhysicsComponent>(component))
m_staticBody.reset();
}
/*!
* \brief Operation to perform when component is detached from this component
*
* \param component Component being detached
*/
void CollisionComponent::OnComponentDetached(BaseComponent& component)
{
if (IsComponent<PhysicsComponent>(component))
InitializeStaticBody();
}
/*!
* \brief Operation to perform when component is detached from an entity
*/
void CollisionComponent::OnDetached()
{
m_staticBody.reset();

View File

@ -9,7 +9,23 @@
namespace Ndk
{
void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index)
/*!
* \ingroup NDK
* \class Ndk::GraphicsComponent
* \brief NDK class that represents the component for graphics
*/
/*!
* \brief Invalidates the data for renderable
*
* \param renderable Renderable to invalidate
* \param flags Flags for the instance
* \param index Index of the renderable to invalidate
*
* \remark Produces a NazaraAssert if index is out of bound
*/
void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable , Nz::UInt32 flags, std::size_t index)
{
NazaraAssert(index < m_renderables.size(), "Invalid renderable index");
NazaraUnused(renderable);
@ -19,6 +35,10 @@ namespace Ndk
r.renderable->InvalidateData(&r.data, flags);
}
/*!
* \brief Operation to perform when component is attached to an entity
*/
void GraphicsComponent::OnAttached()
{
if (m_entity->HasComponent<NodeComponent>())
@ -27,6 +47,12 @@ namespace Ndk
InvalidateTransformMatrix();
}
/*!
* \brief Operation to perform when component is attached to this component
*
* \param component Component being attached
*/
void GraphicsComponent::OnComponentAttached(BaseComponent& component)
{
if (IsComponent<NodeComponent>(component))
@ -38,6 +64,12 @@ namespace Ndk
}
}
/*!
* \brief Operation to perform when component is detached from this component
*
* \param component Component being detached
*/
void GraphicsComponent::OnComponentDetached(BaseComponent& component)
{
if (IsComponent<NodeComponent>(component))
@ -48,6 +80,10 @@ namespace Ndk
}
}
/*!
* \brief Operation to perform when component is detached from an entity
*/
void GraphicsComponent::OnDetached()
{
m_nodeInvalidationSlot.Disconnect();
@ -55,6 +91,12 @@ namespace Ndk
InvalidateTransformMatrix();
}
/*!
* \brief Operation to perform when the node is invalidated
*
* \param node Pointer to the node
*/
void GraphicsComponent::OnNodeInvalidated(const Nz::Node* node)
{
NazaraUnused(node);
@ -63,6 +105,10 @@ namespace Ndk
InvalidateTransformMatrix();
}
/*!
* \brief Updates the bounding volume
*/
void GraphicsComponent::UpdateBoundingVolume() const
{
EnsureTransformMatrixUpdate();
@ -75,6 +121,12 @@ namespace Ndk
m_boundingVolumeUpdated = true;
}
/*!
* \brief Updates the transform matrix of the renderable
*
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
*/
void GraphicsComponent::UpdateTransformMatrix() const
{
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "GraphicsComponent requires NodeComponent");

View File

@ -7,6 +7,19 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::ParticleEmitterComponent
* \brief NDK class that represents the component emitter of particles
*/
/*!
* \brief Sets up the particles
*
* \param mapper Mapper containing layout information of each particle
* \param count Number of particles
*/
void ParticleEmitterComponent::SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const
{
if (m_isActive && m_setupFunc)

View File

@ -12,6 +12,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::PhysicsComponent
* \brief NDK class that represents the component for physics (meant for dynamic objects)
*/
/*!
* \brief Operation to perform when component is attached to an entity
*
* \remark Produces a NazaraAssert if the world does not have a physics system
*/
void PhysicsComponent::OnAttached()
{
World* entityWorld = m_entity->GetWorld();
@ -33,6 +45,14 @@ namespace Ndk
m_object->SetMass(1.f);
}
/*!
* \brief Operation to perform when component is attached to this component
*
* \param component Component being attached
*
* \remark Produces a NazaraAssert if physical object is invalid
*/
void PhysicsComponent::OnComponentAttached(BaseComponent& component)
{
if (IsComponent<CollisionComponent>(component))
@ -42,6 +62,14 @@ namespace Ndk
}
}
/*!
* \brief Operation to perform when component is detached from this component
*
* \param component Component being detached
*
* \remark Produces a NazaraAssert if physical object is invalid
*/
void PhysicsComponent::OnComponentDetached(BaseComponent& component)
{
if (IsComponent<CollisionComponent>(component))
@ -51,6 +79,10 @@ namespace Ndk
}
}
/*!
* \brief Operation to perform when component is detached from an entity
*/
void PhysicsComponent::OnDetached()
{
m_object.reset();

View File

@ -19,6 +19,20 @@ namespace Ndk
constexpr std::size_t s_inputPrefixSize = Nz::CountOf(s_inputPrefix) - 1;
}
/*!
* \ingroup NDK
* \class Ndk::Console
* \brief NDK class that represents a console to help development with Lua scripting
*/
/*!
* \brief Constructs a Console object with a world to interact with
*
* \param world World to interact with
* \param size (Width, Height) of the console
* \param instance Lua instance that will interact with the world
*/
Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) :
m_historyPosition(0),
m_defaultFont(Nz::Font::GetDefault()),
@ -86,18 +100,35 @@ namespace Ndk
Layout();
}
/*!
* \brief Adds a line to the console
*
* \param text New line of text
* \param color Color for the text
*/
void Console::AddLine(const Nz::String& text, const Nz::Color& color)
{
AddLineInternal(text, color);
RefreshHistory();
}
/*!
* \brief Clears the console
*/
void Console::Clear()
{
m_historyLines.clear();
RefreshHistory();
}
/*!
* \brief Sends a character to the console
*
* \param character Character that will be added to the console
*/
void Console::SendCharacter(char32_t character)
{
switch (character)
@ -131,6 +162,12 @@ namespace Ndk
m_inputTextSprite->Update(m_inputDrawer);
}
/*!
* \brief Sends an event to the console
*
* \param event Event to be takin into consideration by the console
*/
void Console::SendEvent(Nz::WindowEvent event)
{
switch (event.type)
@ -170,6 +207,12 @@ namespace Ndk
}
}
/*!
* \brief Sets the character size
*
* \param size Size of the font
*/
void Console::SetCharacterSize(unsigned int size)
{
m_characterSize = size;
@ -182,6 +225,12 @@ namespace Ndk
Layout();
}
/*!
* \brief Sets the console size
*
* \param size (Width, Height) of the console
*/
void Console::SetSize(const Nz::Vector2f& size)
{
m_size = size;
@ -189,6 +238,14 @@ namespace Ndk
Layout();
}
/*!
* \brief Sets the text font
*
* \param font Reference to a valid font
*
* \remark Produces a NazaraAssert if font is invalid or null
*/
void Console::SetTextFont(Nz::FontRef font)
{
NazaraAssert(font && font->IsValid(), "Invalid font");
@ -200,6 +257,12 @@ namespace Ndk
Layout();
}
/*!
* \brief Shows the console
*
* \param show Should the console be showed
*/
void Console::Show(bool show)
{
if (m_opened != show)
@ -213,11 +276,22 @@ namespace Ndk
}
}
/*!
* \brief Adds a line to the history of the console
*
* \param text New line of text
* \param color Color for the text
*/
void Console::AddLineInternal(const Nz::String& text, const Nz::Color& color)
{
m_historyLines.emplace_back(Line{color, text});
}
/*!
* \brief Performs this action when an input is added to the console
*/
void Console::ExecuteInput()
{
Nz::String input = m_inputDrawer.GetText();
@ -237,12 +311,18 @@ namespace Ndk
RefreshHistory();
}
/*!
* \brief Places the console according to its layout
*/
void Console::Layout()
{
unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight;
Ndk::NodeComponent& inputNode = m_input->GetComponent<Ndk::NodeComponent>();
NazaraError(inputNode.GetPosition().ToString());
inputNode.SetPosition(0.f, m_size.y - lineHeight - 5.f);
NazaraError(inputNode.GetPosition().ToString());
float historyHeight = m_size.y - lineHeight - 5.f - 2.f;
m_historyBackgroundSprite->SetSize(m_size.x, historyHeight);
@ -250,14 +330,22 @@ namespace Ndk
m_maxHistoryLines = static_cast<unsigned int>(std::ceil(historyHeight / lineHeight));
Ndk::NodeComponent& historyNode = m_history->GetComponent<Ndk::NodeComponent>();
NazaraError(historyNode.GetPosition().ToString());
historyNode.SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight);
NazaraError(historyNode.GetPosition().ToString());
Ndk::NodeComponent& inputBackgroundNode = m_inputBackground->GetComponent<Ndk::NodeComponent>();
NazaraError(inputBackgroundNode.GetPosition().ToString());
inputBackgroundNode.SetPosition(0.f, historyHeight + 2.f);
NazaraError(inputBackgroundNode.GetPosition().ToString());
m_inputBackgroundSprite->SetSize(m_size.x, m_size.y - historyHeight);
}
/*!
* \brief Refreshes the history of the console
*/
void Console::RefreshHistory()
{
m_historyDrawer.Clear();

View File

@ -8,6 +8,18 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::Entity
* \brief NDK class that represents an entity in a world
*/
/*!
* \brief Constructs a Entity object by move semantic
*
* \param entity Entity to move into this
*/
Entity::Entity(Entity&& entity) :
HandledObject(std::move(entity)),
m_components(std::move(entity.m_components)),
@ -20,35 +32,57 @@ namespace Ndk
{
}
/*!
* \brief Constructs a Entity object linked to a world and with an id
*
* \param world World in which the entity interact
* \param id Identifier of the entity
*/
Entity::Entity(World* world, EntityId id) :
m_id(id),
m_world(world)
{
}
/*!
* \brief Destructs the object and calls Destroy
*
* \see Destroy
*/
Entity::~Entity()
{
Destroy();
}
/*!
* \brief Adds a component to the entity
* \return A reference to the newly added component
*
* \param componentPtr Component to add to the entity
*
* \remark Produces a NazaraAssert if component is nullptr
*/
BaseComponent& Entity::AddComponent(std::unique_ptr<BaseComponent>&& componentPtr)
{
NazaraAssert(componentPtr, "Component must be valid");
ComponentIndex index = componentPtr->GetIndex();
// Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component
// We ensure that the vector has enough space
if (index >= m_components.size())
m_components.resize(index + 1);
// Affectation et retour du component
// Affectation and return of the component
m_components[index] = std::move(componentPtr);
m_componentBits.UnboundedSet(index);
m_removedComponentBits.UnboundedReset(index);
Invalidate();
// On récupère le component et on informe les composants existants du nouvel arrivant
// We get the new component and we alert other existing components of the new one
BaseComponent& component = *m_components[index].get();
component.SetEntity(this);
@ -61,34 +95,57 @@ namespace Ndk
return component;
}
/*!
* \brief Clones the entity
* \return The clone newly created
*
* \remark The close is enable by default, even if the original is disabled
* \remark Produces a NazaraAssert if the entity is not valid
*/
const EntityHandle& Entity::Clone() const
{
///DOC: The clone is enabled by default, even if the original entity is disabled
NazaraAssert(IsValid(), "Invalid entity");
return m_world->CloneEntity(m_id);
}
/*!
* \brief Kills the entity
*/
void Entity::Kill()
{
m_world->KillEntity(this);
}
/*!
* \brief Invalidates the entity
*/
void Entity::Invalidate()
{
// On informe le monde que nous avons besoin d'une mise à jour
// We alert everyone that we have been updated
m_world->Invalidate(m_id);
}
/*!
* \brief Creates the entity
*/
void Entity::Create()
{
m_enabled = true;
m_valid = true;
}
/*!
* \brief Destroys the entity
*/
void Entity::Destroy()
{
// On informe chaque système
// We alert each system
for (std::size_t index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index))
{
if (m_world->HasSystem(index))
@ -104,12 +161,19 @@ namespace Ndk
m_valid = false;
}
/*!
* \brief Destroys a component by index
*
* \param index Index of the component
*
* \remark If component is not available, no action is performed
*/
void Entity::DestroyComponent(ComponentIndex index)
{
///DOC: N'a aucun effet si le component n'est pas présent
if (HasComponent(index))
{
// On récupère le component et on informe les composants du détachement
// We get the component and we alert existing components of the deleted one
BaseComponent& component = *m_components[index].get();
for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
{

View File

@ -5,12 +5,29 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::LuaAPI
* \brief NDK class that represents the api used for Lua
*/
/*!
* \brief Initializes the LuaAPI module
* \return true if initialization is successful
*/
bool LuaAPI::Initialize()
{
s_binding = new LuaBinding;
return true;
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the engine & SDK
*/
void LuaAPI::RegisterClasses(Nz::LuaInstance& instance)
{
if (!s_binding && !Initialize())
@ -22,6 +39,10 @@ namespace Ndk
s_binding->RegisterClasses(instance);
}
/*!
* \brief Uninitializes the LuaAPI module
*/
void LuaAPI::Uninitialize()
{
delete s_binding;

View File

@ -4,6 +4,16 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::LuaBinding
* \brief NDK class that represents the binding between the engine & the SDK with the Lua scripting
*/
/*!
* \brief Binds modules to Lua
*/
LuaBinding::LuaBinding() :
// Core
clockClass("Clock"),
@ -65,6 +75,12 @@ namespace Ndk
#endif
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the engine & SDK
*/
void LuaBinding::RegisterClasses(Nz::LuaInstance& instance)
{
RegisterCore(instance);

View File

@ -6,6 +6,10 @@
namespace Ndk
{
/*!
* \brief Binds Audio module to Lua
*/
void LuaBinding::BindAudio()
{
/*********************************** Nz::Music **********************************/
@ -164,6 +168,12 @@ namespace Ndk
soundEmitter.BindMethod("Stop", &Nz::SoundEmitter::Stop);
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Audio classes
*/
void LuaBinding::RegisterAudio(Nz::LuaInstance& instance)
{
musicClass.Register(instance);

View File

@ -6,6 +6,10 @@
namespace Ndk
{
/*!
* \brief Binds Core module to Lua
*/
void LuaBinding::BindCore()
{
/*********************************** Nz::Clock **********************************/
@ -254,6 +258,12 @@ namespace Ndk
});
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Core classes
*/
void LuaBinding::RegisterCore(Nz::LuaInstance& instance)
{
// Classes

View File

@ -6,6 +6,10 @@
namespace Ndk
{
/*!
* \brief Binds Graphics module to Lua
*/
void LuaBinding::BindGraphics()
{
/*********************************** Nz::InstancedRenderable ***********************************/
@ -40,6 +44,12 @@ namespace Ndk
modelClass.BindMethod("SetSkinCount", &Nz::Model::SetSkinCount);
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Graphics classes
*/
void LuaBinding::RegisterGraphics(Nz::LuaInstance& instance)
{
instancedRenderable.Register(instance);

View File

@ -7,6 +7,10 @@
namespace Ndk
{
/*!
* \brief Binds Math module to Lua
*/
void LuaBinding::BindMath()
{
/*********************************** Nz::EulerAngles **********************************/
@ -673,6 +677,12 @@ namespace Ndk
});
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Math classes
*/
void LuaBinding::RegisterMath(Nz::LuaInstance& instance)
{
eulerAnglesClass.Register(instance);

View File

@ -5,6 +5,10 @@
namespace Ndk
{
/*!
* \brief Binds Network module to Lua
*/
void LuaBinding::BindNetwork()
{
/*********************************** Nz::AbstractSocket **********************************/
@ -132,6 +136,12 @@ namespace Ndk
});
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Network classes
*/
void LuaBinding::RegisterNetwork(Nz::LuaInstance& instance)
{
// Classes

View File

@ -7,10 +7,20 @@
namespace Ndk
{
/*!
* \brief Binds Renderer module to Lua
*/
void LuaBinding::BindRenderer()
{
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Renderer classes
*/
void LuaBinding::RegisterRenderer(Nz::LuaInstance& instance)
{
}

View File

@ -7,6 +7,10 @@
namespace Ndk
{
/*!
* \brief Binds SDK module to Lua
*/
void LuaBinding::BindSDK()
{
/*********************************** Ndk::Application **********************************/
@ -143,6 +147,12 @@ namespace Ndk
#endif
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the SDK classes
*/
void LuaBinding::RegisterSDK(Nz::LuaInstance& instance)
{
// Classes
@ -173,6 +183,14 @@ namespace Ndk
instance.SetGlobal("ComponentType");
}
/*!
* \brief Gets the index of the component
* \return A pointer to the binding linked to a component
*
* \param instance Lua instance that will interact with the component
* \param argIndex Index of the component
*/
LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaInstance& instance, int argIndex)
{
switch (instance.GetType(argIndex))

View File

@ -6,6 +6,10 @@
namespace Ndk
{
/*!
* \brief Binds Utility module to Lua
*/
void LuaBinding::BindUtility()
{
/*********************************** Nz::AbstractImage **********************************/
@ -308,6 +312,12 @@ namespace Ndk
});
}
/*!
* \brief Registers the classes that will be used by the Lua instance
*
* \param instance Lua instance that will interact with the Utility classes
*/
void LuaBinding::RegisterUtility(Nz::LuaInstance& instance)
{
abstractImage.Register(instance);

View File

@ -34,6 +34,19 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::Sdk
* \brief NDK class that represents the software development kit, a set of tools made to ease the conception of application
*/
/*!
* \brief Initializes the Sdk module
* \return true if initialization is successful
*
* \remark Produces a NazaraNotice
*/
bool Sdk::Initialize()
{
if (s_referenceCounter++ > 0)
@ -104,6 +117,12 @@ namespace Ndk
}
}
/*!
* \brief Uninitializes the Sdk module
*
* \remark Produces a NazaraNotice
*/
void Sdk::Uninitialize()
{
if (s_referenceCounter != 1)

View File

@ -6,5 +6,11 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::State
* \brief NDK class that represents a state of your application
*/
State::~State() = default;
}

View File

@ -10,11 +10,29 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::ListenerSystem
* \brief NDK class that represents the audio system
*
* \remark This system is enabled if the entity owns the trait: ListenerComponent and NodeComponent
*/
/*!
* \brief Constructs an ListenerSystem object by default
*/
ListenerSystem::ListenerSystem()
{
Requires<ListenerComponent, NodeComponent>();
}
/*!
* \brief Operation to perform when system is updated
*
* \param elapsedTime Delta time used for the update
*/
void ListenerSystem::OnUpdate(float elapsedTime)
{
NazaraUnused(elapsedTime);
@ -23,18 +41,18 @@ namespace Ndk
for (const Ndk::EntityHandle& entity : GetEntities())
{
// Le listener est-il actif ?
// Is the listener actif ?
const ListenerComponent& listener = entity->GetComponent<ListenerComponent>();
if (!listener.IsActive())
continue;
// On récupère la position et la rotation pour les affecter au listener
// We get the position and the rotation to affect these to the listener
const NodeComponent& node = entity->GetComponent<NodeComponent>();
Nz::Audio::SetListenerPosition(node.GetPosition(Nz::CoordSys_Global));
Nz::Audio::SetListenerRotation(node.GetRotation(Nz::CoordSys_Global));
// On vérifie la présence d'une donnée de vitesse, et on l'affecte
// (La vitesse du listener Audio ne le fait pas se déplacer, mais affecte par exemple l'effet Doppler)
// We verify the presence of a component of velocity
// (The listener'speed does not move it, but disturbs the sound like Doppler effect)
if (entity->HasComponent<VelocityComponent>())
{
const VelocityComponent& velocity = entity->GetComponent<VelocityComponent>();

View File

@ -7,11 +7,29 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::ParticleSystem
* \brief NDK class that represents the particle system
*
* \remark This system is enabled if the entity has the trait: NodeComponent and any of these two: ParticleGroupComponent
*/
/*!
* \brief Constructs an ParticleSystem object by default
*/
ParticleSystem::ParticleSystem()
{
Requires<ParticleGroupComponent>();
}
/*!
* \brief Operation to perform when system is updated
*
* \param elapsedTime Delta time used for the update
*/
void ParticleSystem::OnUpdate(float elapsedTime)
{
for (const Ndk::EntityHandle& entity : GetEntities())

View File

@ -10,24 +10,50 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::PhysicsSystem
* \brief NDK class that represents the physics system
*
* \remark This system is enabled if the entity has the trait: NodeComponent and any of these two: CollisionComponent or PhysicsComponent
* \remark Static objects do not have a velocity specified by the physical engine
*/
/*!
* \brief Constructs an PhysicsSystem object by default
*/
PhysicsSystem::PhysicsSystem()
{
Requires<NodeComponent>();
RequiresAny<CollisionComponent, PhysicsComponent>();
}
/*!
* \brief Constructs a PhysicsSystem object by copy semantic
*
* \param system PhysicsSystem to copy
*/
PhysicsSystem::PhysicsSystem(const PhysicsSystem& system) :
System(system),
m_world()
{
}
/*!
* \brief Operation to perform when entity is validated for the system
*
* \param entity Pointer to the entity
* \param justAdded Is the entity newly added
*/
void PhysicsSystem::OnEntityValidation(Entity* entity, bool justAdded)
{
// Si l'entité ne vient pas d'être ajoutée au système, il est possible qu'elle fasse partie du mauvais tableau
// If entity has not been just added to the system, it is possible that it does not own to the right array
if (!justAdded)
{
// On prend le tableau inverse de celui dont l'entité devrait faire partie
// We take the inverted array from which the entity should belong to
auto& entities = (entity->HasComponent<PhysicsComponent>()) ? m_staticObjects : m_dynamicObjects;
entities.Remove(entity);
}
@ -36,6 +62,12 @@ namespace Ndk
entities.Insert(entity);
}
/*!
* \brief Operation to perform when system is updated
*
* \param elapsedTime Delta time used for the update
*/
void PhysicsSystem::OnUpdate(float elapsedTime)
{
m_world.Step(elapsedTime);
@ -63,8 +95,8 @@ namespace Ndk
Nz::Quaternionf newRotation = node.GetRotation(Nz::CoordSys_Global);
Nz::Vector3f newPosition = node.GetPosition(Nz::CoordSys_Global);
// Pour déplacer des objets statiques et assurer les collisions, il faut leur définir une vitesse
// (note importante: le moteur physique n'applique pas la vitesse sur les objets statiques)
// To move static objects and ensure their collisions, we have to specify them a velocity
// (/!\: the physical motor does not apply the speed on static objects)
if (newPosition != oldPosition)
{
physObj->SetPosition(newPosition);

View File

@ -14,6 +14,21 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::RenderSystem
* \brief NDK class that represents the rendering system
*
* \remark This system is enabled if the entity is a 'camera' with the trait: CameraComponent and NodeComponent
* or a drawable element with trait: GraphicsComponent and NodeComponent
* or a light element with trait: LightComponent and NodeComponent
* or a set of particles with trait: ParticleGroupComponent
*/
/*!
* \brief Constructs an RenderSystem object by default
*/
RenderSystem::RenderSystem() :
m_coordinateSystemMatrix(Nz::Matrix4f::Identity()),
m_coordinateSystemInvalidated(true)
@ -23,6 +38,12 @@ namespace Ndk
SetUpdateRate(0.f);
}
/*!
* \brief Operation to perform when an entity is removed
*
* \param entity Pointer to the entity
*/
void RenderSystem::OnEntityRemoved(Entity* entity)
{
m_cameras.Remove(entity);
@ -33,6 +54,13 @@ namespace Ndk
m_pointSpotLights.Remove(entity);
}
/*!
* \brief Operation to perform when entity is validated for the system
*
* \param entity Pointer to the entity
* \param justAdded Is the entity newly added
*/
void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded)
{
NazaraUnused(justAdded);
@ -82,6 +110,12 @@ namespace Ndk
m_particleGroups.Remove(entity);
}
/*!
* \brief Operation to perform when system is updated
*
* \param elapsedTime Delta time used for the update
*/
void RenderSystem::OnUpdate(float elapsedTime)
{
NazaraUnused(elapsedTime);
@ -146,6 +180,12 @@ namespace Ndk
}
}
/*!
* \brief Updates the directional shadow maps according to the position of the viewer
*
* \param viewer Viewer of the scene
*/
void RenderSystem::UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer)
{
if (!m_shadowRT.IsValid())
@ -191,6 +231,10 @@ namespace Ndk
}
}
/*!
* \brief Updates the point spot shadow maps
*/
void RenderSystem::UpdatePointSpotShadowMaps()
{
if (!m_shadowRT.IsValid())

View File

@ -9,12 +9,31 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::VelocitySystem
* \brief NDK class that represents the velocity system
*
* \remark This system is enabled if the entity owns the trait: NodeComponent and VelocityComponent
* but it's disabled with the trait: PhysicsComponent
*/
/*!
* \brief Constructs an VelocitySystem object by default
*/
VelocitySystem::VelocitySystem()
{
Requires<NodeComponent, VelocityComponent>();
Excludes<PhysicsComponent>();
}
/*!
* \brief Operation to perform when system is updated
*
* \param elapsedTime Delta time used for the update
*/
void VelocitySystem::OnUpdate(float elapsedTime)
{
for (const Ndk::EntityHandle& entity : GetEntities())

View File

@ -16,12 +16,28 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::World
* \brief NDK class that represents a world
*/
/*!
* \brief Destructs the object and calls Clear
*
* \see Clear
*/
World::~World() noexcept
{
// La destruction doit se faire dans un ordre précis
// The destruct must be done in an ordered way
Clear();
}
/*!
* \brief Adds default systems to the world
*/
void World::AddDefaultSystems()
{
AddSystem<PhysicsSystem>();
@ -34,40 +50,49 @@ namespace Ndk
#endif
}
/*!
* \brief Creates an entity in the world
* \return The entity created
*/
const EntityHandle& World::CreateEntity()
{
EntityId id;
if (!m_freeIdList.empty())
{
// On récupère un identifiant
// We get an identifier
id = m_freeIdList.back();
m_freeIdList.pop_back();
}
else
{
// On alloue une nouvelle entité
// We allocate a new entity
id = m_entities.size();
// Impossible d'utiliser emplace_back à cause de la portée
// We can't use emplace_back due to the scope
m_entities.push_back(Entity(this, id));
}
// On initialise l'entité et on l'ajoute à la liste des entités vivantes
// We initialise the entity and we add it to the list of alive entities
Entity& entity = m_entities[id].entity;
entity.Create();
m_aliveEntities.emplace_back(&entity);
m_entities[id].aliveIndex = m_aliveEntities.size()-1;
m_entities[id].aliveIndex = m_aliveEntities.size() - 1;
return m_aliveEntities.back();
}
/*!
* \brief Clears the world from every entities
*
* \remark Every handles are correctly invalidated, entities are immediately invalidated
*/
void World::Clear() noexcept
{
///DOC: Tous les handles sont correctement invalidés, les entités sont immédiatement invalidées
// Destruction des entités d'abord, et des handles ensuite
// ceci pour éviter que les handles n'informent les entités inutilement lors de leur destruction
// First, destruction of entities, then handles
// This is made to avoid that handle warn uselessly entities before their destruction
m_entities.clear();
m_aliveEntities.clear();
@ -75,6 +100,15 @@ namespace Ndk
m_killedEntities.Clear();
}
/*!
* \brief Clones the entity
* \return The clone newly created
*
* \param id Identifier of the entity
*
* \remark Produces a NazaraError if the entity to clone does not exist
*/
const EntityHandle& World::CloneEntity(EntityId id)
{
EntityHandle original = GetEntity(id);
@ -96,14 +130,29 @@ 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)
{
///DOC: Ignoré si l'entité est invalide
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))
@ -115,9 +164,15 @@ namespace Ndk
}
}
/*!
* \brief Updates the world
*
* \remark Produces a NazaraAssert if an entity is invalid
*/
void World::Update()
{
// Gestion des entités tuées depuis le dernier appel
// Handle killed entities before last call
for (std::size_t i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i))
{
EntityBlock& block = m_entities[i];
@ -125,32 +180,32 @@ namespace Ndk
NazaraAssert(entity.IsValid(), "Entity must be valid");
// Remise en file d'attente de l'identifiant d'entité
// Send back the identifier of the entity to the free queue
m_freeIdList.push_back(entity.GetId());
// Destruction de l'entité (invalidation du handle par la même occasion)
// Destruction of the entity (invalidation of handle by the same way)
entity.Destroy();
// Nous allons sortir le handle de la liste des entités vivantes
// en swappant le handle avec le dernier handle, avant de pop
// We take out the handle from the list of alive entities
// With the idiom swap and pop
NazaraAssert(block.aliveIndex < m_aliveEntities.size(), "Alive index out of range");
if (block.aliveIndex < m_aliveEntities.size()-1) // S'il ne s'agit pas du dernier handle
if (block.aliveIndex < m_aliveEntities.size() - 1) // If it's not the last handle
{
EntityHandle& lastHandle = m_aliveEntities.back();
EntityHandle& myHandle = m_aliveEntities[block.aliveIndex];
myHandle = std::move(lastHandle);
// On n'oublie pas de corriger l'indice associé à l'entité
// We don't forget to update the index associated to the entity
m_entities[myHandle->GetId()].aliveIndex = block.aliveIndex;
}
m_aliveEntities.pop_back();
}
m_killedEntities.Reset();
// Gestion des entités nécessitant une mise à jour de leurs systèmes
// Handle of entities which need an update from the systems
for (std::size_t i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i))
{
NazaraAssert(i < m_entities.size(), "Entity index out of range");

View File

@ -14,17 +14,10 @@ TOOL.Includes = {
TOOL.Files = {
"../tests/main.cpp",
"../tests/Engine/**.cpp"
"../tests/Engine/**.cpp",
"../tests/SDK/**.cpp"
}
TOOL.Libraries = {
"NazaraCore",
"NazaraAudio",
"NazaraLua",
"NazaraGraphics",
"NazaraRenderer",
"NazaraNetwork",
"NazaraNoise",
"NazaraPhysics",
"NazaraUtility"
"NazaraSDK"
}

View File

@ -97,6 +97,7 @@ namespace Nz
MaterialPipelineRef MaterialPipeline::New(Args&&... args)
{
std::unique_ptr<MaterialPipeline> object(new MaterialPipeline(std::forward<Args>(args)...));
object->SetPersistent(false);
return object.release();
}
}

View File

@ -45,20 +45,21 @@ namespace Nz
}
template<typename T>
// Les parenthèses autour de la condition sont nécesaires pour que GCC compile ça
// The parentheses are needed for GCC
typename std::enable_if<(sizeof(T) > sizeof(UInt32)), unsigned int>::type IntegralLog2(T number)
{
static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed");
// L'algorithme pour le logarithme base 2 (au dessus) ne fonctionne qu'avec des nombres au plus 32bits
// ce code décompose les nombres plus grands en nombres 32 bits par masquage et bit shifting
// Masking and shifting bits to the right (to bring it back to 32 bits)
// Call of the function with 32 bits number, if the result is non-null we have our answer
for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32))
{
// Le masque 32 bits sur la partie du nombre qu'on traite actuellement
// The 32 bits mask on the part we are treating
T mask = T(std::numeric_limits<UInt32>::max()) << i*8;
T val = (number & mask) >> i*8; // Masquage et shifting des bits vers la droite (pour le ramener sur 32bits)
T val = (number & mask) >> i*8; // Masking and shifting bits to the right (to bring it back to 32 bits)
// Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse
// Call of the function with 32 bits number, if the result is non-null we have our answer
unsigned int log2 = IntegralLog2<UInt32>(val);
if (log2)
return log2 + i*8;
@ -75,20 +76,20 @@ namespace Nz
}
template<typename T>
// Les parenthèses autour de la condition sont nécesaires pour que GCC compile ça
// The parentheses are needed for GCC
typename std::enable_if<(sizeof(T) > sizeof(UInt32)), unsigned int>::type IntegralLog2Pot(T number)
{
static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed");
// L'algorithme pour le logarithme base 2 (au dessus) ne fonctionne qu'avec des nombres au plus 32bits
// ce code décompose les nombres plus grands en nombres 32 bits par masquage et bit shifting
// The algorithm for logarithm in base 2 only works with numbers greather than 32 bits
// This code subdivides the biggest number into 32 bits ones
for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32))
{
// Le masque 32 bits sur la partie du nombre qu'on traite actuellement
// The 32 bits mask on the part we are treating
T mask = T(std::numeric_limits<UInt32>::max()) << i*8;
UInt32 val = UInt32((number & mask) >> i*8); // Masquage et shifting des bits vers la droite (pour le ramener sur 32bits)
UInt32 val = UInt32((number & mask) >> i*8); // Masking and shifting bits to the right (to bring it back to 32 bits)
// Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse
// Call of the function with 32 bits number, if the result is non-null we have our answer
unsigned int log2 = IntegralLog2Pot<UInt32>(val);
if (log2 || val == 1)
return log2 + i*8;
@ -99,7 +100,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Approaches the objective, beginning with value and with increment
* \return The nearest value of the objective you can get with the value and the increment for one step
*
@ -121,7 +122,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Clamps value between min and max and returns the expected value
* \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval
*
@ -137,7 +138,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets number of bits set in the number
* \return The number of bits set to 1
*
@ -160,7 +161,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Converts degree to radian
* \return The representation in radian of the angle in degree (0..2*pi)
*
@ -174,7 +175,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the unit from degree and convert it according to NAZARA_MATH_ANGLE_RADIAN
* \return Express the degrees
*
@ -192,7 +193,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the unit from radian and convert it according to NAZARA_MATH_ANGLE_RADIAN
* \return Express the radians
*
@ -210,7 +211,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the nearest power of two for the number
* \return First power of two containing the number
*
@ -229,7 +230,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits
*
@ -257,7 +258,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits
*
@ -279,7 +280,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits
*
@ -295,7 +296,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits
*
@ -312,7 +313,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits
*
@ -328,7 +329,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits
*
@ -345,7 +346,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits + 1 for the dot
*
@ -360,7 +361,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits + 1 for the dot
*
@ -375,7 +376,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
* \return Number of digits + 1 for the dot
*
@ -390,7 +391,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the log in base 2 of integral number
* \return Log of the number (floor)
*
@ -408,7 +409,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the log in base 2 of integral number, only works for power of two !
* \return Log of the number
*
@ -426,7 +427,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the power of integrals
* \return base^exponent for integral
*
@ -445,7 +446,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Interpolates the value to other one with a factor of interpolation
* \return A new value which is the interpolation of two values
*
@ -466,7 +467,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Multiplies X and Y, then add Z
* \return The result of X * Y + Z
*
@ -508,7 +509,7 @@ namespace Nz
#endif
/*!
* \ingroup math
* \ingroup math
* \brief Normalizes the angle
* \return Normalized value between 0..2*(pi if radian or 180 if degrees)
*
@ -534,7 +535,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Checks whether two numbers are equal
* \return true if they are equal within a certain epsilon
*
@ -550,7 +551,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Checks whether two numbers are equal
* \return true if they are equal within the max difference
*
@ -571,7 +572,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Converts the number to String
* \return String representation of the number
*
@ -623,7 +624,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Converts radian to degree
* \return The representation in degree of the angle in radian (0..360)
*
@ -637,7 +638,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Converts the string to number
* \return Number which is represented by the string
*
@ -699,7 +700,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the degree from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN
* \return Express in degrees
*
@ -717,7 +718,7 @@ namespace Nz
}
/*!
* \ingroup math
* \ingroup math
* \brief Gets the radian from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN
* \return Express in radians
*

View File

@ -75,7 +75,7 @@ namespace Nz
}
/*!
* \brief Initializes the sprite librairies
* \brief Initializes the sprite library
* \return true If successful
*
* \remark Produces a NazaraError if the sprite library failed to be initialized
@ -93,7 +93,7 @@ namespace Nz
}
/*!
* \brief Uninitializes the sprite librairies
* \brief Uninitializes the sprite library
*/
void Sprite::Uninitialize()

View File

@ -90,6 +90,13 @@ namespace Nz
}
}
/*!
* \brief Initializes the tilemap library
* \return true If successful
*
* \remark Produces a NazaraError if the tilemap library failed to be initialized
*/
bool TileMap::Initialize()
{
if (!TileMapLibrary::Initialize())
@ -101,6 +108,10 @@ namespace Nz
return true;
}
/*!
* \brief Uninitializes the tilemap library
*/
void TileMap::Uninitialize()
{
TileMapLibrary::Uninitialize();

View File

@ -93,7 +93,7 @@ namespace Nz
}
/*!
* \brief Uninitializes the Core module
* \brief Uninitializes the Network module
*
* \remark Produces a NazaraNotice
*/

View File

@ -0,0 +1,22 @@
#include <NDK/Application.hpp>
#include <Catch/catch.hpp>
SCENARIO("Application", "[NDK][APPLICATION]")
{
GIVEN("An application")
{
Ndk::Application application;
application.AddWorld();
Nz::Window& window = application.AddWindow<Nz::Window>();
WHEN("We close the open window")
{
window.Close();
THEN("Application should close")
{
REQUIRE(!application.Run());
}
}
}
}

View File

@ -0,0 +1,64 @@
#include <NDK/System.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#include <NDK/World.hpp>
#include <Catch/catch.hpp>
namespace
{
class TestSystem : public Ndk::System<TestSystem>
{
public:
TestSystem()
{
Requires<Ndk::VelocityComponent>();
Excludes<Ndk::NodeComponent>();
}
~TestSystem() = default;
static Ndk::SystemIndex systemIndex;
private:
void OnUpdate(float elapsedTime) override
{
}
};
Ndk::SystemIndex TestSystem::systemIndex;
}
SCENARIO("BaseSystem", "[NDK][BASESYSTEM]")
{
GIVEN("Our TestSystem")
{
Ndk::World world;
Ndk::BaseSystem& system = world.AddSystem<TestSystem>();
REQUIRE(&system.GetWorld() == &world);
WHEN("We add an entity")
{
const Ndk::EntityHandle& entity = world.CreateEntity();
entity->AddComponent<Ndk::VelocityComponent>();
THEN("System should have it")
{
world.Update(1.f);
REQUIRE(system.HasEntity(entity));
}
}
WHEN("We add an entity with excluded component")
{
const Ndk::EntityHandle& entity = world.CreateEntity();
entity->AddComponent<Ndk::VelocityComponent>();
entity->AddComponent<Ndk::NodeComponent>();
THEN("System should not have it")
{
world.Update(1.f);
REQUIRE(!system.HasEntity(entity));
}
}
}
}

View File

@ -0,0 +1,31 @@
#include <NDK/Component.hpp>
#include <Catch/catch.hpp>
namespace
{
class TestComponent : public Ndk::Component<TestComponent>
{
public:
static Ndk::ComponentIndex componentIndex;
};
Ndk::ComponentIndex TestComponent::componentIndex;
}
SCENARIO("Component", "[NDK][COMPONENT]")
{
GIVEN("Our TestComponent")
{
TestComponent testComponent;
WHEN("We clone it")
{
std::unique_ptr<Ndk::BaseComponent> clone = testComponent.Clone();
THEN("We should get a copy")
{
REQUIRE(dynamic_cast<TestComponent*>(clone.get()) != nullptr);
}
}
}
}

101
tests/SDK/NDK/Entity.cpp Normal file
View File

@ -0,0 +1,101 @@
#include <NDK/World.hpp>
#include <NDK/Component.hpp>
#include <Catch/catch.hpp>
namespace
{
class UpdatableComponent : public Ndk::Component<UpdatableComponent>
{
public:
bool IsUpdated()
{
return m_updated;
}
void SetUpdated()
{
m_updated = true;
}
static Ndk::ComponentIndex componentIndex;
private:
bool m_updated = false;
};
Ndk::ComponentIndex UpdatableComponent::componentIndex;
class UpdateSystem : public Ndk::System<UpdateSystem>
{
public:
UpdateSystem()
{
Requires<UpdatableComponent>();
}
~UpdateSystem() = default;
static Ndk::SystemIndex systemIndex;
private:
void OnUpdate(float elapsedTime) override
{
for (const Ndk::EntityHandle& entity : GetEntities())
{
UpdatableComponent& updatable = entity->GetComponent<UpdatableComponent>();
updatable.SetUpdated();
}
}
};
Ndk::SystemIndex UpdateSystem::systemIndex;
}
SCENARIO("Entity", "[NDK][ENTITY]")
{
GIVEN("A world & an entity")
{
Ndk::World world;
Ndk::BaseSystem& system = world.AddSystem<UpdateSystem>();
const Ndk::EntityHandle& entity = world.CreateEntity();
WHEN("We add our UpdateComponent")
{
UpdatableComponent& updatableComponent = entity->AddComponent<UpdatableComponent>();
REQUIRE(!updatableComponent.IsUpdated());
THEN("Update the world should update the entity's component")
{
world.Update(1.f);
UpdatableComponent& updatableComponentGet = entity->GetComponent<UpdatableComponent>();
REQUIRE(updatableComponentGet.IsUpdated());
}
THEN("Update the world should not update the entity's component if it's disabled")
{
entity->Enable(false);
world.Update(1.f);
UpdatableComponent& updatableComponentGet = entity->GetComponent<UpdatableComponent>();
REQUIRE(!updatableComponentGet.IsUpdated());
}
THEN("We can remove its component")
{
entity->RemoveComponent(Ndk::GetComponentIndex<UpdatableComponent>());
world.Update(1.f);
REQUIRE(!entity->HasComponent<UpdatableComponent>());
}
}
WHEN("We kill our entity")
{
entity->Kill();
world.Update(1.f);
THEN("It's no more valid")
{
REQUIRE(!world.IsEntityValid(entity));
}
}
}
}

View File

@ -0,0 +1,41 @@
#include <NDK/EntityList.hpp>
#include <NDK/World.hpp>
#include <Catch/catch.hpp>
SCENARIO("EntityList", "[NDK][ENTITYLIST]")
{
GIVEN("A world & a set of entities")
{
Ndk::World world;
const Ndk::EntityHandle& entity = world.CreateEntity();
Ndk::EntityList entityList;
entityList.Insert(entity);
WHEN("We ask if entity is in there")
{
THEN("These results are expected")
{
REQUIRE(entityList.Has(entity->GetId()));
const Ndk::EntityHandle& entity = world.CreateEntity();
REQUIRE(!entityList.Has(entity->GetId()));
}
}
WHEN("We remove then insert")
{
entityList.Remove(*entityList.begin());
THEN("Set should be empty")
{
REQUIRE(entityList.empty());
}
entityList.Insert(entity);
THEN("With one element")
{
REQUIRE(!entityList.empty());
}
}
}
}

View File

@ -0,0 +1,29 @@
#include <NDK/EntityOwner.hpp>
#include <NDK/World.hpp>
#include <Catch/catch.hpp>
SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]")
{
GIVEN("A world & an entity")
{
Ndk::World world;
const Ndk::EntityHandle& entity = world.CreateEntity();
WHEN("We set the ownership of the entity to our owner")
{
Ndk::EntityOwner entityOwner(entity);
THEN("Entity is still valid")
{
REQUIRE(entity.IsValid());
}
THEN("Resetting or getting out of scope is no more valid")
{
entityOwner.Reset();
world.Update(1.f);
REQUIRE(!entity.IsValid());
}
}
}
}

View File

@ -0,0 +1,48 @@
#include <NDK/StateMachine.hpp>
#include <Catch/catch.hpp>
class TestState : 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
{
m_isUpdated = true;
}
private:
bool m_isUpdated;
};
SCENARIO("State & StateMachine", "[NDK][STATE]")
{
GIVEN("A statemachine with our TestState")
{
std::shared_ptr<TestState> testState = std::make_shared<TestState>();
Ndk::StateMachine stateMachine(testState);
REQUIRE(!testState->IsUpdated());
WHEN("We update our machine")
{
stateMachine.Update(1.f);
THEN("Our state has been updated")
{
REQUIRE(testState->IsUpdated());
}
}
}
}

42
tests/SDK/NDK/System.cpp Normal file
View File

@ -0,0 +1,42 @@
#include <NDK/System.hpp>
#include <Catch/catch.hpp>
namespace
{
class TestSystem : public Ndk::System<TestSystem>
{
public:
TestSystem()
{
}
~TestSystem() = default;
static Ndk::SystemIndex systemIndex;
private:
void OnUpdate(float elapsedTime) override
{
}
};
Ndk::SystemIndex TestSystem::systemIndex;
}
SCENARIO("System", "[NDK][SYSTEM]")
{
GIVEN("Our TestSystem")
{
TestSystem testSystem;
WHEN("We clone it")
{
std::unique_ptr<Ndk::BaseSystem> clone = testSystem.Clone();
THEN("We should get a copy")
{
REQUIRE(dynamic_cast<TestSystem*>(clone.get()) != nullptr);
}
}
}
}

View File

@ -0,0 +1,43 @@
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/World.hpp>
#include <NDK/Components/ListenerComponent.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Catch/catch.hpp>
SCENARIO("ListenerSystem", "[NDK][LISTENERSYSTEM]")
{
GIVEN("A world and an entity with listener & node components")
{
Ndk::World world;
const Ndk::EntityHandle& entity = world.CreateEntity();
Ndk::ListenerComponent& listenerComponent = entity->AddComponent<Ndk::ListenerComponent>();
Ndk::NodeComponent& nodeComponent = entity->AddComponent<Ndk::NodeComponent>();
WHEN("We move our entity")
{
Nz::Vector3f position = Nz::Vector3f::Unit() * 3.f;
nodeComponent.SetPosition(position);
Nz::Quaternionf rotation = Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::Up());
nodeComponent.SetRotation(rotation);
world.Update(1.f);
THEN("Our listener should have moved")
{
REQUIRE(Nz::Audio::GetListenerPosition() == position);
REQUIRE(Nz::Audio::GetListenerRotation() == rotation);
}
THEN("With a component of velocity")
{
Ndk::VelocityComponent& velocityComponent = entity->AddComponent<Ndk::VelocityComponent>();
Nz::Vector3f velocity = Nz::Vector3f::Unit() * 2.f;
velocityComponent.linearVelocity = velocity;
world.Update(1.f);
REQUIRE(Nz::Audio::GetListenerVelocity() == velocity);
}
}
}
}

View File

@ -0,0 +1,34 @@
#include <NDK/Systems/PhysicsSystem.hpp>
#include <NDK/World.hpp>
#include <NDK/Components/CollisionComponent.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/PhysicsComponent.hpp>
#include <Catch/catch.hpp>
SCENARIO("PhysicsSystem", "[NDK][PHYSICSSYSTEM]")
{
GIVEN("A world and a static entity & a dynamic entity")
{
Ndk::World world;
const Ndk::EntityHandle& staticEntity = world.CreateEntity();
Ndk::CollisionComponent& collisionComponentStatic = staticEntity->AddComponent<Ndk::CollisionComponent>();
Ndk::NodeComponent& nodeComponentStatic = staticEntity->AddComponent<Ndk::NodeComponent>();
const Ndk::EntityHandle& dynamicEntity = world.CreateEntity();
Ndk::NodeComponent& nodeComponentDynamic = dynamicEntity->AddComponent<Ndk::NodeComponent>();
Ndk::PhysicsComponent& physicsComponentDynamic = dynamicEntity->AddComponent<Ndk::PhysicsComponent>();
WHEN("We make collide these two entities")
{
nodeComponentDynamic.SetPosition(-Nz::Vector3f::UnitZ());
physicsComponentDynamic.AddForce(Nz::Vector3f::UnitZ());
THEN("The dynamic entity should have hit the static one")
{
world.Update(1.f); // On origin
world.Update(1.f); // On origin due to collision
REQUIRE(nodeComponentStatic.GetPosition().SquaredDistance(nodeComponentDynamic.GetPosition()) < 0.2f);
}
}
}
}

View File

@ -0,0 +1,44 @@
#include <NDK/Systems/RenderSystem.hpp>
#include <NDK/World.hpp>
#include <NDK/Components/CameraComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/LightComponent.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/ParticleGroupComponent.hpp>
#include <Nazara/Graphics/Sprite.hpp>
#include <Catch/catch.hpp>
SCENARIO("RenderSystem", "[NDK][RenderSystem]")
{
GIVEN("A world with a camera, a drawable, a light and some particles")
{
Ndk::World world;
const Ndk::EntityHandle& cameraEntity = world.CreateEntity();
Ndk::CameraComponent& cameraComponentCamera = cameraEntity->AddComponent<Ndk::CameraComponent>();
Ndk::NodeComponent& nodeComponentCamera = cameraEntity->AddComponent<Ndk::NodeComponent>();
const Ndk::EntityHandle& drawableEntity = world.CreateEntity();
Ndk::GraphicsComponent& graphicsComponentDrawable = drawableEntity->AddComponent<Ndk::GraphicsComponent>();
Nz::SpriteRef sprite = Nz::Sprite::New();
graphicsComponentDrawable.Attach(sprite);
Ndk::NodeComponent& nodeComponentDrawable = drawableEntity->AddComponent<Ndk::NodeComponent>();
const Ndk::EntityHandle& lightEntity = world.CreateEntity();
Ndk::LightComponent& lightComponentLight = lightEntity->AddComponent<Ndk::LightComponent>();
Ndk::NodeComponent& nodeComponentLight = lightEntity->AddComponent<Ndk::NodeComponent>();
const Ndk::EntityHandle& particlesEntity = world.CreateEntity();
Ndk::ParticleGroupComponent& particleGroupComponentParticles = particlesEntity->AddComponent<Ndk::ParticleGroupComponent>(1, Nz::ParticleLayout_Sprite);
WHEN("We change the render technique to ForwardRenderTechnique")
{
Ndk::RenderSystem& renderSystem = world.GetSystem<Ndk::RenderSystem>();
renderSystem.ChangeRenderTechnique<Nz::ForwardRenderTechnique>();
THEN("The render system should be ForwardRenderTechnique")
{
REQUIRE(renderSystem.GetRenderTechnique().GetType() == Nz::RenderTechniqueType_BasicForward);
}
}
}
}

View File

@ -0,0 +1,28 @@
#include <NDK/Systems/VelocitySystem.hpp>
#include <NDK/World.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#include <Catch/catch.hpp>
SCENARIO("VelocitySystem", "[NDK][VELOCITYSYSTEM]")
{
GIVEN("A world and an entity with velocity & node components")
{
Ndk::World world;
const Ndk::EntityHandle& entity = world.CreateEntity();
Ndk::VelocityComponent& velocityComponent = entity->AddComponent<Ndk::VelocityComponent>();
Ndk::NodeComponent& nodeComponent = entity->AddComponent<Ndk::NodeComponent>();
WHEN("We give a speed to our entity")
{
Nz::Vector3f velocity = Nz::Vector3f::Unit() * 2.f;
velocityComponent.linearVelocity = velocity;
world.Update(1.f);
THEN("Our entity should have moved")
{
REQUIRE(nodeComponent.GetPosition().SquaredDistance(velocity) < 0.2f);
}
}
}
}

103
tests/SDK/NDK/World.cpp Normal file
View File

@ -0,0 +1,103 @@
#include <NDK/World.hpp>
#include <NDK/Component.hpp>
#include <Catch/catch.hpp>
namespace
{
class UpdatableComponent : public Ndk::Component<UpdatableComponent>
{
public:
bool IsUpdated()
{
return m_updated;
}
void SetUpdated()
{
m_updated = true;
}
static Ndk::ComponentIndex componentIndex;
private:
bool m_updated = false;
};
Ndk::ComponentIndex UpdatableComponent::componentIndex;
class UpdateSystem : public Ndk::System<UpdateSystem>
{
public:
UpdateSystem()
{
Requires<UpdatableComponent>();
}
~UpdateSystem() = default;
static Ndk::SystemIndex systemIndex;
private:
void OnUpdate(float elapsedTime) override
{
for (const Ndk::EntityHandle& entity : GetEntities())
{
UpdatableComponent& updatable = entity->GetComponent<UpdatableComponent>();
updatable.SetUpdated();
}
}
};
Ndk::SystemIndex UpdateSystem::systemIndex;
}
SCENARIO("World", "[NDK][WORLD]")
{
GIVEN("A brave new world and the update system")
{
Ndk::World world;
Ndk::BaseSystem& system = world.AddSystem<UpdateSystem>();
WHEN("We had a new entity with an updatable component and a system")
{
const Ndk::EntityHandle& entity = world.CreateEntity();
UpdatableComponent& component = entity->AddComponent<UpdatableComponent>();
THEN("We can get our entity and our system")
{
const Ndk::EntityHandle& fetchedEntity = world.GetEntity(entity->GetId());
REQUIRE(fetchedEntity->GetWorld() == &world);
}
THEN("We can clone it")
{
const Ndk::EntityHandle& clone = world.CloneEntity(entity->GetId());
REQUIRE(world.IsEntityValid(clone));
}
}
AND_WHEN("We update our world with our entity")
{
REQUIRE(&world.GetSystem(UpdateSystem::systemIndex) == &world.GetSystem<UpdateSystem>());
const Ndk::EntityHandle& entity = world.CreateEntity();
UpdatableComponent& component = entity->AddComponent<UpdatableComponent>();
THEN("Our entity component must be updated")
{
world.Update(1.f);
REQUIRE(component.IsUpdated());
}
THEN("We kill our entity")
{
REQUIRE(entity->IsValid());
world.KillEntity(entity);
world.Update(1.f);
REQUIRE(!world.IsEntityValid(entity));
}
}
}
}