Merge branch 'master' into gui

Former-commit-id: ab617839e9da6d7576bb2ee260aa5a53691042a0 [formerly 0b7b354ef529ca3b9795f8042772890125942701] [formerly 1390383adba6cfc347d513cc290927a6d254d733 [formerly 6a6a1a4f56d26a6601d8a5e53a6fc99dbcc187be]]
Former-commit-id: 1b19d5fda60c06437b1c874c424258a83dad0f77 [formerly 2423a7b5c83f99d5097c3cf5dc647033161ad78a]
Former-commit-id: 744ec2d55571319ba6266ac69b6a51ba8deb0b4a
This commit is contained in:
Lynix
2016-09-06 13:57:25 +02:00
215 changed files with 5468 additions and 3899 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,18 +8,35 @@
#define NDK_APPLICATION_HPP
#include <NDK/Prerequesites.hpp>
#include <NDK/EntityOwner.hpp>
#include <NDK/World.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Utility/Window.hpp>
#include <map>
#include <list>
#include <set>
#include <vector>
#ifndef NDK_SERVER
#include <NDK/Console.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Lua/LuaInstance.hpp>
#include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Utility/Window.hpp>
#endif
namespace Ndk
{
class NDK_API Application
{
public:
#ifndef NDK_SERVER
struct ConsoleOverlay;
struct FPSCounterOverlay;
#endif
inline Application();
Application(int argc, char* argv[]);
Application(const Application&) = delete;
Application(Application&&) = delete;
inline ~Application();
@@ -29,8 +46,27 @@ namespace Ndk
#endif
template<typename... Args> World& AddWorld(Args&&... args);
#ifndef NDK_SERVER
inline void EnableConsole(bool enable);
inline void EnableFPSCounter(bool enable);
inline ConsoleOverlay& GetConsoleOverlay(std::size_t windowIndex = 0U);
inline FPSCounterOverlay& GetFPSCounterOverlay(std::size_t windowIndex = 0U);
#endif
inline const std::set<Nz::String>& GetOptions() const;
inline const std::map<Nz::String, Nz::String>& GetParameters() const;
inline float GetUpdateTime() const;
inline bool HasOption(const Nz::String& option) const;
inline bool HasParameter(const Nz::String& key, Nz::String* value) const;
#ifndef NDK_SERVER
inline bool IsConsoleEnabled() const;
inline bool IsFPSCounterEnabled() const;
#endif
bool Run();
#ifndef NDK_SERVER
@@ -44,13 +80,63 @@ namespace Ndk
inline static Application* Instance();
#ifndef NDK_SERVER
struct ConsoleOverlay
{
std::unique_ptr<Console> console;
Nz::LuaInstance lua;
NazaraSlot(Nz::EventHandler, OnEvent, eventSlot);
NazaraSlot(Nz::EventHandler, OnKeyPressed, keyPressedSlot);
NazaraSlot(Nz::RenderTarget, OnRenderTargetSizeChange, resizedSlot);
NazaraSlot(Nz::Log, OnLogWrite, logSlot);
};
struct FPSCounterOverlay
{
Nz::TextSpriteRef sprite;
EntityOwner entity;
float elapsedTime = 0.f;
unsigned int frameCount = 0;
};
#endif
private:
#ifndef NDK_SERVER
std::vector<std::unique_ptr<Nz::Window>> m_windows;
enum OverlayFlags
{
OverlayFlags_Console = 0x1,
OverlayFlags_FPSCounter = 0x2
};
struct WindowInfo
{
inline WindowInfo(std::unique_ptr<Nz::Window>&& window);
Nz::RenderTarget* renderTarget;
std::unique_ptr<Nz::Window> window;
std::unique_ptr<ConsoleOverlay> console;
std::unique_ptr<FPSCounterOverlay> fpsCounter;
std::unique_ptr<World> overlayWorld;
};
void SetupConsole(WindowInfo& info);
void SetupFPSCounter(WindowInfo& info);
void SetupOverlay(WindowInfo& info);
template<typename T> void SetupWindow(WindowInfo& info, T* renderTarget, std::true_type /*isRenderTarget*/);
template<typename T> void SetupWindow(WindowInfo& /*info*/, T* /*renderTarget*/, std::false_type /*isNotRenderTarget*/);
std::vector<WindowInfo> m_windows;
#endif
std::map<Nz::String, Nz::String> m_parameters;
std::set<Nz::String> m_options;
std::list<World> m_worlds;
Nz::Clock m_updateClock;
#ifndef NDK_SERVER
Nz::UInt32 m_overlayFlags;
bool m_exitOnClosedWindows;
#endif
bool m_shouldQuit;

View File

@@ -2,14 +2,23 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Application.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <type_traits>
#include <NDK/Sdk.hpp>
namespace Ndk
{
/*!
* \brief Constructs an Application object without passing command-line arguments
*
* This calls Sdk::Initialize()
*
* \remark Only one Application instance can exist at a time
*/
inline Application::Application() :
#ifndef NDK_SERVER
m_overlayFlags(0U),
m_exitOnClosedWindows(true),
#endif
m_shouldQuit(false),
@@ -24,6 +33,11 @@ namespace Ndk
Sdk::Initialize();
}
/*!
* \brief Destructs the application object
*
* This destroy all worlds and windows and then calls Sdk::Uninitialize
*/
inline Application::~Application()
{
m_worlds.clear();
@@ -31,24 +45,43 @@ 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)
{
static_assert(std::is_base_of<Nz::Window, T>::value, "Type must inherit Window");
m_windows.emplace_back(new T(std::forward<Args>(args)...));
return static_cast<T&>(*m_windows.back().get());
m_windows.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
WindowInfo& info = m_windows.back();
T& window = static_cast<T&>(*info.window.get()); //< Warning: ugly
SetupWindow(info, &window, std::is_base_of<Nz::RenderTarget, T>());
return window;
}
#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 +89,241 @@ namespace Ndk
return m_worlds.back();
}
/*!
* \brief Enable/disable debug console
*
* \param enable Should the console overlay be enabled
*/
#ifndef NDK_SERVER
inline void Application::EnableConsole(bool enable)
{
if (enable != ((m_overlayFlags & OverlayFlags_Console) != 0))
{
if (enable)
{
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
SetupOverlay(info);
}
for (WindowInfo& info : m_windows)
{
if (info.renderTarget)
SetupConsole(info);
}
m_overlayFlags |= OverlayFlags_Console;
}
else
{
for (WindowInfo& info : m_windows)
info.console.reset();
m_overlayFlags &= ~OverlayFlags_Console;
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
info.overlayWorld.reset();
}
}
}
}
#endif
/*!
* \brief Enable/disable debug FPS counter
*
* \param enable Should the FPS counter be displayed
*/
#ifndef NDK_SERVER
inline void Application::EnableFPSCounter(bool enable)
{
if (enable != ((m_overlayFlags & OverlayFlags_FPSCounter) != 0))
{
if (enable)
{
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
SetupOverlay(info);
}
for (WindowInfo& info : m_windows)
{
if (info.renderTarget)
SetupFPSCounter(info);
}
m_overlayFlags |= OverlayFlags_FPSCounter;
}
else
{
for (WindowInfo& info : m_windows)
info.fpsCounter.reset();
m_overlayFlags &= ~OverlayFlags_FPSCounter;
if (m_overlayFlags == 0)
{
for (WindowInfo& info : m_windows)
info.overlayWorld.reset();
}
}
}
}
#endif
/*!
* \brief Gets the console overlay for a specific window
*
* \param windowIndex Index of the window to get
*
* \remark The console overlay must be enabled
*
* \return A reference to the console overlay of the window
*
* \see IsConsoleOverlayEnabled
*/
#ifndef NDK_SERVER
inline Application::ConsoleOverlay& Application::GetConsoleOverlay(std::size_t windowIndex)
{
NazaraAssert(m_overlayFlags & OverlayFlags_Console, "Console overlay is not enabled");
NazaraAssert(windowIndex <= m_windows.size(), "Window index is out of range");
return *m_windows[windowIndex].console;
}
#endif
/*!
* \brief Gets the console overlay for a specific window
*
* \param windowIndex Index of the window to get
*
* \remark The console overlay must be enabled
*
* \return A reference to the console overlay of the window
*
* \see IsFPSCounterEnabled
*/
#ifndef NDK_SERVER
inline Application::FPSCounterOverlay& Application::GetFPSCounterOverlay(std::size_t windowIndex)
{
NazaraAssert(m_overlayFlags & OverlayFlags_FPSCounter, "FPS counter overlay is not enabled");
NazaraAssert(windowIndex <= m_windows.size(), "Window index is out of range");
return *m_windows[windowIndex].fpsCounter;
}
#endif
/*!
* \brief Gets the options used to start the application
*
* Options are defined as "-optionName" in command-line and are always lower-case
*
* \return Command-line options
*/
inline const std::set<Nz::String>& Application::GetOptions() const
{
return m_options;
}
/*!
* \brief Gets the parameters used to start the application
*
* Parameters are defined as "-key=value" in command-line, their key is lower-case but value capitals are kept.
*
* \return Command-line parameters
*/
inline const std::map<Nz::String, Nz::String>& Application::GetParameters() const
{
return m_parameters;
}
/*!
* \brief Gets the update time of the application
* \return Update rate
*/
inline float Application::GetUpdateTime() const
{
return m_updateTime;
}
/*!
* \brief Query for a command-line option
*
* \param option Option name
*
* \remark option must be lower-case
*
* \return True if option is present
*
* \see GetOptions
*/
inline bool Application::HasOption(const Nz::String& option) const
{
return m_options.count(option) != 0;
}
/*!
* \brief Query for a command-line option
*
* \param key Parameter name
* \param value Optional string to receive the parameter value
*
* \remark key must be lower-case
*
* \return True if parameter is present
*
* \see GetParameters
*/
inline bool Application::HasParameter(const Nz::String& key, Nz::String* value) const
{
auto it = m_parameters.find(key);
if (it == m_parameters.end())
return false;
if (value)
*value = it->second;
return true;
}
/*!
* \brief Checks if the console overlay is enabled
*
* \remark This has nothing to do with the visibility state of the console
*
* \return True if the console overlay is enabled
*
* \see GetConsoleOverlay
*/
#ifndef NDK_SERVER
inline bool Application::IsConsoleEnabled() const
{
return (m_overlayFlags & OverlayFlags_Console) != 0;
}
#endif
/*!
* \brief Checks if the FPS counter overlay is enabled
* \return True if the FPS counter overlay is enabled
*
* \see GetFPSCounterOverlay
*/
#ifndef NDK_SERVER
inline bool Application::IsFPSCounterEnabled() const
{
return (m_overlayFlags & OverlayFlags_FPSCounter) != 0;
}
#endif
/*!
* \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,13 +331,52 @@ 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;
}
#ifndef NDK_SERVER
template<typename T>
inline void Application::SetupWindow(WindowInfo& info, T* renderTarget, std::true_type)
{
info.renderTarget = renderTarget;
if (m_overlayFlags)
{
SetupOverlay(info);
if (m_overlayFlags & OverlayFlags_Console)
SetupConsole(info);
if (m_overlayFlags & OverlayFlags_FPSCounter)
SetupFPSCounter(info);
}
}
template<typename T>
inline void Application::SetupWindow(WindowInfo&, T*, std::false_type)
{
}
inline Application::WindowInfo::WindowInfo(std::unique_ptr<Nz::Window>&& window) :
window(std::move(window)),
renderTarget(nullptr)
{
}
#endif
}

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

@@ -27,7 +27,9 @@ namespace Ndk
BaseSystem(BaseSystem&&) noexcept = default;
virtual ~BaseSystem();
virtual BaseSystem* Clone() const = 0;
inline void Enable(bool enable = true);
virtual std::unique_ptr<BaseSystem> Clone() const = 0;
bool Filters(const Entity* entity) const;
@@ -36,6 +38,8 @@ namespace Ndk
inline float GetUpdateRate() const;
inline World& GetWorld() const;
inline bool IsEnabled() const;
inline bool HasEntity(const Entity* entity) const;
inline void SetUpdateRate(float updatePerSecond);
@@ -86,6 +90,7 @@ namespace Ndk
Nz::Bitset<> m_requiredComponents;
SystemIndex m_systemIndex;
World* m_world;
bool m_updateEnabled;
float m_updateCounter;
float m_updateRate;

View File

@@ -2,46 +2,109 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/BaseSystem.hpp>
#include <Nazara/Core/Error.hpp>
#include <type_traits>
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)
{
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),
m_systemIndex(system.m_systemIndex),
m_updateEnabled(system.m_updateEnabled),
m_updateCounter(0.f),
m_updateRate(system.m_updateRate)
{
}
/*!
* \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)
@@ -50,14 +113,29 @@ 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())
return;
if (m_updateRate > 0.f)
{
m_updateCounter += elapsedTime;
@@ -72,6 +150,10 @@ namespace Ndk
OnUpdate(elapsedTime);
}
/*!
* \brief Excludes some component from the system
*/
template<typename ComponentType>
void BaseSystem::Excludes()
{
@@ -80,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()
{
@@ -87,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()
{
@@ -105,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()
{
@@ -112,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()
{
@@ -125,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()
{
@@ -132,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");
@@ -149,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");
@@ -156,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");
@@ -174,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;
@@ -186,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

@@ -32,10 +32,11 @@ namespace Ndk
inline void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;
inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
inline void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);
inline void Clear();
inline void Detach(const Nz::InstancedRenderableRef& renderable);
inline void Detach(const Nz::InstancedRenderable* renderable);
inline void EnsureBoundingVolumeUpdate() const;
inline void EnsureTransformMatrixUpdate() const;
@@ -75,20 +76,31 @@ namespace Ndk
Renderable(Renderable&& renderable) noexcept :
data(std::move(renderable.data)),
renderable(std::move(renderable.renderable)),
dataUpdated(renderable.dataUpdated)
dataUpdated(renderable.dataUpdated),
renderableInvalidationSlot(std::move(renderable.renderableInvalidationSlot)),
renderableReleaseSlot(std::move(renderable.renderableReleaseSlot))
{
}
~Renderable()
{
// Disconnect release slot before releasing instanced renderable reference
renderableReleaseSlot.Disconnect();
}
Renderable& operator=(Renderable&& r) noexcept
{
data = std::move(r.data);
dataUpdated = r.dataUpdated;
renderable = std::move(r.renderable);
renderableInvalidationSlot = std::move(r.renderableInvalidationSlot);
renderableReleaseSlot = std::move(r.renderableReleaseSlot);
return *this;
}
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot);
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot);
mutable Nz::InstancedRenderable::InstanceData data;
Nz::InstancedRenderableRef renderable;

View File

@@ -2,11 +2,19 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/World.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#include <algorithm>
#include "GraphicsComponent.hpp"
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,14 +28,23 @@ 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();
Ndk::RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem<Ndk::RenderSystem>();
for (const Renderable& object : m_renderables)
{
if (!object.dataUpdated)
{
object.data.transformMatrix = Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), Nz::Matrix4f::ConcatenateAffine(object.data.localMatrix, m_transformMatrix));
object.renderable->UpdateData(&object.data);
object.dataUpdated = true;
}
@@ -36,17 +53,35 @@ 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)
{
return Attach(renderable, Nz::Matrix4f::Identity(), renderOrder);
}
inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder)
{
m_renderables.emplace_back(m_transformMatrix);
Renderable& r = m_renderables.back();
r.data.localMatrix = localMatrix;
r.data.renderOrder = renderOrder;
r.renderable = std::move(renderable);
r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1));
r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size() - 1));
r.renderableReleaseSlot.Connect(r.renderable->OnInstancedRenderableRelease, this, &GraphicsComponent::Detach);
InvalidateBoundingVolume();
}
/*!
* \brief Clears every renderable elements
*/
inline void GraphicsComponent::Clear()
{
m_renderables.clear();
@@ -54,7 +89,13 @@ namespace Ndk
InvalidateBoundingVolume();
}
inline void GraphicsComponent::Detach(const Nz::InstancedRenderableRef& renderable)
/*!
* \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)
{
@@ -67,18 +108,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");
@@ -88,11 +145,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();
@@ -100,17 +167,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

@@ -17,7 +17,7 @@ namespace Ndk
using ParticleGroupComponentHandle = Nz::ObjectHandle<ParticleGroupComponent>;
class NDK_API ParticleGroupComponent : public Component<ParticleGroupComponent>, public Nz::ParticleGroup
class NDK_API ParticleGroupComponent : public Component<ParticleGroupComponent>, public Nz::ParticleGroup, public Nz::HandledObject<ParticleGroupComponent>
{
public:
inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout);
@@ -25,6 +25,12 @@ namespace Ndk
ParticleGroupComponent(const ParticleGroupComponent&) = default;
~ParticleGroupComponent() = default;
void AddEmitter(Entity* emitter);
using ParticleGroup::AddEmitter;
void RemoveEmitter(Entity* emitter);
using ParticleGroup::RemoveEmitter;
static ComponentIndex componentIndex;
};
}

View File

@@ -1,17 +1,77 @@
#include "ParticleGroupComponent.hpp"
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Components/ParticleGroupComponent.hpp>
#include <NDK/Components/ParticleEmitterComponent.hpp>
#include <Nazara/Core/Error.hpp>
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");
NazaraAssert(emitter->HasComponent<ParticleEmitterComponent>(), "Entity must have a NodeComponent");
auto& emitterComponent = emitter->GetComponent<ParticleEmitterComponent>();
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");
NazaraAssert(emitter->HasComponent<ParticleEmitterComponent>(), "Entity must have a NodeComponent");
auto& emitterComponent = emitter->GetComponent<ParticleEmitterComponent>();
ParticleGroup::RemoveEmitter(&emitterComponent);
}
}

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

@@ -34,10 +34,14 @@ namespace Ndk
BaseComponent& AddComponent(std::unique_ptr<BaseComponent>&& component);
template<typename ComponentType, typename... Args> ComponentType& AddComponent(Args&&... args);
inline void Enable(bool enable);
const EntityHandle& Clone() const;
inline void Enable(bool enable = true);
inline BaseComponent& GetComponent(ComponentIndex index);
template<typename ComponentType> ComponentType& GetComponent();
inline const BaseComponent& GetComponent(ComponentIndex index) const;
template<typename ComponentType> const ComponentType& GetComponent() const;
inline const Nz::Bitset<>& GetComponentBits() const;
inline EntityId GetId() const;
inline const Nz::Bitset<>& GetSystemBits() const;
@@ -52,8 +56,8 @@ namespace Ndk
inline bool IsEnabled() const;
inline bool IsValid() const;
void RemoveAllComponents();
void RemoveComponent(ComponentIndex index);
inline void RemoveAllComponents();
inline void RemoveComponent(ComponentIndex index);
template<typename ComponentType> void RemoveComponent();
inline Nz::String ToString() const;
@@ -67,6 +71,10 @@ namespace Ndk
void Create();
void Destroy();
void DestroyComponent(ComponentIndex index);
inline Nz::Bitset<>& GetRemovedComponentBits();
inline void RegisterSystem(SystemIndex index);
inline void SetWorld(World* world) noexcept;
@@ -75,6 +83,7 @@ namespace Ndk
std::vector<std::unique_ptr<BaseComponent>> m_components;
Nz::Bitset<> m_componentBits;
Nz::Bitset<> m_removedComponentBits;
Nz::Bitset<> m_systemBits;
EntityId m_id;
World* m_world;

View File

@@ -2,6 +2,7 @@
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Entity.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <algorithm>
@@ -10,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)
@@ -29,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();
@@ -40,41 +62,114 @@ 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
{
NazaraAssert(HasComponent(index), "This component is not part of the entity");
BaseComponent* component = m_components[index].get();
NazaraAssert(component, "Invalid component pointer");
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
{
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
{
@@ -84,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()
{
@@ -103,17 +236,46 @@ namespace Ndk
RemoveComponent(index);
}
/*!
* \brief Gives a string representation
* \return A string representation of the object: "Entity(GetId())"
*/
inline Nz::String Entity::ToString() const
{
Nz::StringStream ss;
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");
@@ -121,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);
@@ -132,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,6 +4,7 @@
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_SYSTEMS_PARTICLESYSTEM_HPP
#define NDK_SYSTEMS_PARTICLESYSTEM_HPP
@@ -27,3 +28,4 @@ namespace Ndk
#include <NDK/Systems/ParticleSystem.inl>
#endif // NDK_SYSTEMS_PARTICLESYSTEM_HPP
#endif // NDK_SERVER

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

@@ -28,8 +28,8 @@ namespace Ndk
inline RenderSystem(const RenderSystem& renderSystem);
~RenderSystem() = default;
template<typename T> void ChangeRenderTechnique();
inline void ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique);
template<typename T> T& ChangeRenderTechnique();
inline Nz::AbstractRenderTechnique& ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique);
inline const Nz::BackgroundRef& GetDefaultBackground() const;
inline const Nz::Matrix4f& GetCoordinateSystemMatrix() const;

View File

@@ -4,57 +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 void RenderSystem::ChangeRenderTechnique()
inline T& RenderSystem::ChangeRenderTechnique()
{
ChangeRenderTechnique(std::make_unique<T>());
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>()));
}
inline void RenderSystem::ChangeRenderTechnique(std::unique_ptr<Nz::AbstractRenderTechnique>&& renderTechnique)
/*!
* \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;
@@ -64,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;
@@ -73,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;
@@ -82,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,6 +43,7 @@ namespace Ndk
inline EntityList CreateEntities(unsigned int count);
void Clear() noexcept;
const EntityHandle& CloneEntity(EntityId id);
const EntityHandle& GetEntity(EntityId id);
inline const EntityList& GetEntities();

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);