Merge remote-tracking branch 'refs/remotes/origin/master' into gui

Former-commit-id: 79463d2933cbd8bc6f0b9de5021a83ef7b5aa29b [formerly 3292aa8d849c9c569315d342fdcb17002547593e] [formerly bbb62690f0e47f3248ed524657fb3e01abaf1dcd [formerly e327e6aad9af55fcf96cea232148729cb73a78d4]]
Former-commit-id: cae74a258a54f3b0dc8962d02a39bc2d5d0b6fb2 [formerly 2c3dc59631a1d6923c52216498d97c7b08151520]
Former-commit-id: 289eb5a199a6d775b4e0c5dc905aedc518d67e67
This commit is contained in:
Lynix 2016-08-09 13:58:57 +02:00
commit 7d1ddffc53
456 changed files with 20884 additions and 6482 deletions

2
.gitattributes vendored
View File

@ -1,2 +1,4 @@
# Auto detect text files and perform LF normalization # Auto detect text files and perform LF normalization
* text=auto * text=auto
extlibs/* linguist-vendored
NazaraModuleTemplate/* linguist-vendored

4
.gitignore vendored
View File

@ -1,10 +1,13 @@
# Nazara build # Nazara build
build/config.lua
examples/bin/*.exe examples/bin/*.exe
examples/bin/*.pdb examples/bin/*.pdb
examples/bin/*.dll examples/bin/*.dll
examples/bin/*.so examples/bin/*.so
tests/*.exe tests/*.exe
tests/*.pdb tests/*.pdb
tests/*.dll
tests/*.so
lib/* lib/*
# Feature page # Feature page
@ -35,6 +38,7 @@ build/**/*.vcxprojResolveAssemblyReference.cache
build/**/*.nativecodeanalysis.all.xml build/**/*.nativecodeanalysis.all.xml
build/**/*.nativecodeanalysis.xml build/**/*.nativecodeanalysis.xml
build/**/*.VC.opendb build/**/*.VC.opendb
build/**/*.VC.db
# Compiled Object files # Compiled Object files
build/**/*.slo build/**/*.slo

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Jérôme Leclercq
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -33,6 +33,10 @@ namespace Ndk
bool Run(); bool Run();
#ifndef NDK_SERVER
inline void MakeExitOnLastWindowClosed(bool exitOnClosedWindows);
#endif
inline void Quit(); inline void Quit();
Application& operator=(const Application&) = delete; Application& operator=(const Application&) = delete;

View File

@ -61,6 +61,13 @@ namespace Ndk
return m_updateTime; return m_updateTime;
} }
#ifndef NDK_SERVER
inline void Application::MakeExitOnLastWindowClosed(bool exitOnClosedWindows)
{
m_exitOnClosedWindows = exitOnClosedWindows;
}
#endif
inline void Application::Quit() inline void Application::Quit()
{ {
m_shouldQuit = true; m_shouldQuit = true;

View File

@ -26,7 +26,7 @@ namespace Ndk
inline ComponentIndex BaseComponent::RegisterComponent(ComponentId id, Factory factoryFunc) inline ComponentIndex BaseComponent::RegisterComponent(ComponentId id, Factory factoryFunc)
{ {
// Nous allons rajouter notre composant à la fin // Nous allons rajouter notre composant à la fin
ComponentIndex index = s_entries.size(); ComponentIndex index = static_cast<ComponentIndex>(s_entries.size());
s_entries.resize(index + 1); s_entries.resize(index + 1);
// On récupère et on affecte // On récupère et on affecte

View File

@ -28,13 +28,11 @@ namespace Ndk
template<typename ComponentType> template<typename ComponentType>
ComponentIndex Component<ComponentType>::RegisterComponent(ComponentId id) ComponentIndex Component<ComponentType>::RegisterComponent(ComponentId id)
{ {
// Il faut que notre composant possède un constructeur par défaut (pour la factory)
static_assert(std::is_default_constructible<ComponentType>::value, "ComponentType must be default-constructible");
// On utilise les lambda pour créer une fonction factory // On utilise les lambda pour créer une fonction factory
auto factory = []() -> BaseComponent* auto factory = []() -> BaseComponent*
{ {
return new ComponentType; return nullptr; //< Temporary workaround to allow non-default-constructed components, will be updated for serialization
//return new ComponentType;
}; };
return BaseComponent::RegisterComponent(id, factory); return BaseComponent::RegisterComponent(id, factory);

View File

@ -1,20 +1,19 @@
// This file was automatically generated on 03 Mar 2016 at 14:09:12 // This file was automatically generated on 30 Jul 2016 at 15:29:16
#pragma once #pragma once
#ifndef NDK_COMPONENTS_GLOBAL_HPP #ifndef NDK_COMPONENTS_GLOBAL_HPP
#define NDK_COMPONENTS_GLOBAL_HPP #define NDK_COMPONENTS_GLOBAL_HPP
#include <NDK/Components/CollisionComponent.hpp>
#include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/PhysicsComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#ifndef NDK_SERVER
#include <NDK/Components/CameraComponent.hpp> #include <NDK/Components/CameraComponent.hpp>
#include <NDK/Components/CollisionComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/LightComponent.hpp> #include <NDK/Components/LightComponent.hpp>
#include <NDK/Components/ListenerComponent.hpp> #include <NDK/Components/ListenerComponent.hpp>
#endif #include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/ParticleEmitterComponent.hpp>
#include <NDK/Components/ParticleGroupComponent.hpp>
#include <NDK/Components/PhysicsComponent.hpp>
#include <NDK/Components/VelocityComponent.hpp>
#endif // NDK_COMPONENTS_GLOBAL_HPP #endif // NDK_COMPONENTS_GLOBAL_HPP

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_CAMERACOMPONENT_HPP #ifndef NDK_COMPONENTS_CAMERACOMPONENT_HPP
#define NDK_COMPONENTS_CAMERACOMPONENT_HPP #define NDK_COMPONENTS_CAMERACOMPONENT_HPP
@ -108,3 +109,4 @@ namespace Ndk
#include <NDK/Components/CameraComponent.inl> #include <NDK/Components/CameraComponent.inl>
#endif // NDK_COMPONENTS_CAMERACOMPONENT_HPP #endif // NDK_COMPONENTS_CAMERACOMPONENT_HPP
#endif // NDK_SERVER

View File

@ -2,17 +2,17 @@
// This file is part of the "Nazara Development Kit" // This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp // For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <NDK/Components/CameraComponent.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Algorithm.hpp> #include <Nazara/Math/Algorithm.hpp>
#include "CameraComponent.hpp"
namespace Ndk namespace Ndk
{ {
inline CameraComponent::CameraComponent() : inline CameraComponent::CameraComponent() :
m_projectionType(Nz::ProjectionType_Perspective), m_projectionType(Nz::ProjectionType_Perspective),
m_targetRegion(0.f, 0.f, 1.f, 1.f), m_targetRegion(0.f, 0.f, 1.f, 1.f),
m_size(0.f),
m_target(nullptr), m_target(nullptr),
m_size(0.f),
m_frustumUpdated(false), m_frustumUpdated(false),
m_projectionMatrixUpdated(false), m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false), m_viewMatrixUpdated(false),
@ -30,8 +30,8 @@ namespace Ndk
AbstractViewer(camera), AbstractViewer(camera),
m_projectionType(camera.m_projectionType), m_projectionType(camera.m_projectionType),
m_targetRegion(camera.m_targetRegion), m_targetRegion(camera.m_targetRegion),
m_size(camera.m_size),
m_target(nullptr), m_target(nullptr),
m_size(camera.m_size),
m_frustumUpdated(false), m_frustumUpdated(false),
m_projectionMatrixUpdated(false), m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false), m_viewMatrixUpdated(false),

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP #ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP #define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
@ -22,6 +23,8 @@ namespace Ndk
friend class RenderSystem; friend class RenderSystem;
public: public:
using RenderableList = std::vector<Nz::InstancedRenderableRef>;
GraphicsComponent() = default; GraphicsComponent() = default;
inline GraphicsComponent(const GraphicsComponent& graphicsComponent); inline GraphicsComponent(const GraphicsComponent& graphicsComponent);
~GraphicsComponent() = default; ~GraphicsComponent() = default;
@ -30,16 +33,23 @@ namespace Ndk
inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
inline void Clear();
inline void Detach(const Nz::InstancedRenderableRef& renderable);
inline void EnsureBoundingVolumeUpdate() const; inline void EnsureBoundingVolumeUpdate() const;
inline void EnsureTransformMatrixUpdate() const; inline void EnsureTransformMatrixUpdate() const;
inline void GetAttachedRenderables(RenderableList* renderables) const;
inline std::size_t GetAttachedRenderableCount() const;
inline const Nz::BoundingVolumef& GetBoundingVolume() const; inline const Nz::BoundingVolumef& GetBoundingVolume() const;
static ComponentIndex componentIndex; static ComponentIndex componentIndex;
private: private:
inline void InvalidateBoundingVolume(); inline void InvalidateBoundingVolume();
void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index); void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index);
inline void InvalidateRenderables(); inline void InvalidateRenderables();
inline void InvalidateTransformMatrix(); inline void InvalidateTransformMatrix();
@ -56,12 +66,28 @@ namespace Ndk
struct Renderable struct Renderable
{ {
Renderable(Nz::Matrix4f& transformMatrix) : Renderable(const Nz::Matrix4f& transformMatrix) :
data(transformMatrix), data(transformMatrix),
dataUpdated(false) dataUpdated(false)
{ {
} }
Renderable(Renderable&& renderable) noexcept :
data(std::move(renderable.data)),
renderable(std::move(renderable.renderable)),
dataUpdated(renderable.dataUpdated)
{
}
Renderable& operator=(Renderable&& r) noexcept
{
data = std::move(r.data);
dataUpdated = r.dataUpdated;
renderable = std::move(r.renderable);
return *this;
}
NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot); NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot);
mutable Nz::InstancedRenderable::InstanceData data; mutable Nz::InstancedRenderable::InstanceData data;
@ -80,3 +106,4 @@ namespace Ndk
#include <NDK/Components/GraphicsComponent.inl> #include <NDK/Components/GraphicsComponent.inl>
#endif // NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP #endif // NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#endif // NDK_SERVER

View File

@ -3,11 +3,13 @@
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp // For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <algorithm> #include <algorithm>
#include "GraphicsComponent.hpp"
namespace Ndk namespace Ndk
{ {
inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) : inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) :
Component(graphicsComponent), Component(graphicsComponent),
HandledObject(graphicsComponent),
m_boundingVolume(graphicsComponent.m_boundingVolume), m_boundingVolume(graphicsComponent.m_boundingVolume),
m_transformMatrix(graphicsComponent.m_transformMatrix), m_transformMatrix(graphicsComponent.m_transformMatrix),
m_boundingVolumeUpdated(graphicsComponent.m_boundingVolumeUpdated), m_boundingVolumeUpdated(graphicsComponent.m_boundingVolumeUpdated),
@ -45,6 +47,26 @@ namespace Ndk
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
inline void GraphicsComponent::Clear()
{
m_renderables.clear();
InvalidateBoundingVolume();
}
inline void GraphicsComponent::Detach(const Nz::InstancedRenderableRef& renderable)
{
for (auto it = m_renderables.begin(); it != m_renderables.end(); ++it)
{
if (it->renderable == renderable)
{
InvalidateBoundingVolume();
m_renderables.erase(it);
break;
}
}
}
inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const
{ {
if (!m_boundingVolumeUpdated) if (!m_boundingVolumeUpdated)
@ -57,6 +79,20 @@ namespace Ndk
UpdateTransformMatrix(); UpdateTransformMatrix();
} }
inline void GraphicsComponent::GetAttachedRenderables(RenderableList* renderables) const
{
NazaraAssert(renderables, "Invalid renderable list");
renderables->reserve(renderables->size() + m_renderables.size());
for (const Renderable& r : m_renderables)
renderables->push_back(r.renderable);
}
inline std::size_t GraphicsComponent::GetAttachedRenderableCount() const
{
return m_renderables.size();
}
inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const
{ {
EnsureBoundingVolumeUpdate(); EnsureBoundingVolumeUpdate();

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_LIGHTCOMPONENT_HPP #ifndef NDK_COMPONENTS_LIGHTCOMPONENT_HPP
#define NDK_COMPONENTS_LIGHTCOMPONENT_HPP #define NDK_COMPONENTS_LIGHTCOMPONENT_HPP
@ -28,3 +29,4 @@ namespace Ndk
#include <NDK/Components/LightComponent.inl> #include <NDK/Components/LightComponent.inl>
#endif // NDK_COMPONENTS_LIGHTCOMPONENT_HPP #endif // NDK_COMPONENTS_LIGHTCOMPONENT_HPP
#endif // NDK_SERVER

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_LISTENERCOMPONENT_HPP #ifndef NDK_COMPONENTS_LISTENERCOMPONENT_HPP
#define NDK_COMPONENTS_LISTENERCOMPONENT_HPP #define NDK_COMPONENTS_LISTENERCOMPONENT_HPP
@ -14,11 +15,11 @@ namespace Ndk
class NDK_API ListenerComponent : public Component<ListenerComponent> class NDK_API ListenerComponent : public Component<ListenerComponent>
{ {
public: public:
ListenerComponent(); inline ListenerComponent();
~ListenerComponent() = default; ~ListenerComponent() = default;
bool IsActive() const; inline bool IsActive() const;
void SetActive(bool active = true); inline void SetActive(bool active = true);
static ComponentIndex componentIndex; static ComponentIndex componentIndex;
@ -30,3 +31,4 @@ namespace Ndk
#include <NDK/Components/ListenerComponent.inl> #include <NDK/Components/ListenerComponent.inl>
#endif // NDK_COMPONENTS_LISTENERCOMPONENT_HPP #endif // NDK_COMPONENTS_LISTENERCOMPONENT_HPP
#endif // NDK_SERVER

View File

@ -0,0 +1,46 @@
// 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
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP
#define NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP
#include <Nazara/Graphics/ParticleEmitter.hpp>
#include <Nazara/Graphics/ParticleGroup.hpp>
#include <NDK/Component.hpp>
namespace Ndk
{
class NDK_API ParticleEmitterComponent : public Component<ParticleEmitterComponent>, public Nz::ParticleEmitter
{
public:
using SetupFunc = std::function<void(const EntityHandle& /*entity*/, Nz::ParticleMapper& /*mapper*/, unsigned int /*count*/)>;
inline ParticleEmitterComponent();
ParticleEmitterComponent(const ParticleEmitterComponent& emitter) = default;
ParticleEmitterComponent(ParticleEmitterComponent&& emitter) = default;
~ParticleEmitterComponent() = default;
void Enable(bool active = true);
inline bool IsActive() const;
inline void SetSetupFunc(SetupFunc func);
static ComponentIndex componentIndex;
private:
void SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const override;
SetupFunc m_setupFunc;
bool m_isActive;
};
}
#include <NDK/Components/ParticleEmitterComponent.inl>
#endif // NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP
#endif // NDK_SERVER

View File

@ -0,0 +1,28 @@
// 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/ParticleEmitterComponent.hpp>
namespace Ndk
{
inline ParticleEmitterComponent::ParticleEmitterComponent() :
m_isActive(true)
{
}
inline void Ndk::ParticleEmitterComponent::Enable(bool active)
{
m_isActive = active;
}
inline bool ParticleEmitterComponent::IsActive() const
{
return m_isActive;
}
inline void Ndk::ParticleEmitterComponent::SetSetupFunc(SetupFunc func)
{
m_setupFunc = std::move(func);
}
}

View File

@ -0,0 +1,35 @@
// 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
#pragma once
#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP
#define NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP
#include <Nazara/Graphics/ParticleGroup.hpp>
#include <NDK/Component.hpp>
namespace Ndk
{
class ParticleGroupComponent;
using ParticleGroupComponentHandle = Nz::ObjectHandle<ParticleGroupComponent>;
class NDK_API ParticleGroupComponent : public Component<ParticleGroupComponent>, public Nz::ParticleGroup
{
public:
inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout);
inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration);
ParticleGroupComponent(const ParticleGroupComponent&) = default;
~ParticleGroupComponent() = default;
static ComponentIndex componentIndex;
};
}
#include <NDK/Components/ParticleGroupComponent.inl>
#endif // NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP
#endif // NDK_SERVER

View File

@ -0,0 +1,17 @@
#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
namespace Ndk
{
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout) :
ParticleGroup(maxParticleCount, layout)
{
}
inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration) :
ParticleGroup(maxParticleCount, std::move(declaration))
{
}
}

View File

@ -84,8 +84,12 @@ namespace Nz
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag<FontParams>) inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag<FontParams>)
{ {
NazaraUnused(params);
instance.CheckType(index, Nz::LuaType_Table); instance.CheckType(index, Nz::LuaType_Table);
// Structure is empty for now
return 1; return 1;
} }
@ -96,8 +100,8 @@ namespace Nz
params->animated = instance.CheckField<bool>("Animated", params->animated); params->animated = instance.CheckField<bool>("Animated", params->animated);
params->center = instance.CheckField<bool>("Center", params->center); params->center = instance.CheckField<bool>("Center", params->center);
params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs); params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs);
//params->matrix = instance.CheckField<Matrix4f>("Matrix", params->matrix);
params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers); params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers);
params->scale = instance.CheckField<Vector3f>("Scale", params->scale);
return 1; return 1;
} }
@ -255,14 +259,14 @@ namespace Nz
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag<Ndk::EntityHandle>) inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag<Ndk::EntityHandle>)
{ {
*handle = std::move(*static_cast<Ndk::EntityHandle*>(instance.CheckUserdata(index, "Entity"))); *handle = *static_cast<Ndk::EntityHandle*>(instance.CheckUserdata(index, "Entity"));
return 1; return 1;
} }
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag<Ndk::WorldHandle>) inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag<Ndk::WorldHandle>)
{ {
*handle = std::move(*static_cast<Ndk::WorldHandle*>(instance.CheckUserdata(index, "World"))); *handle = *static_cast<Ndk::WorldHandle*>(instance.CheckUserdata(index, "World"));
return 1; return 1;
} }

View File

@ -13,11 +13,11 @@ namespace Ndk
{ {
class StateMachine; class StateMachine;
class State class NDK_API State
{ {
public: public:
State() = default; State() = default;
~State() = default; virtual ~State();
virtual void Enter(StateMachine& fsm) = 0; virtual void Enter(StateMachine& fsm) = 0;
virtual void Leave(StateMachine& fsm) = 0; virtual void Leave(StateMachine& fsm) = 0;

View File

@ -23,6 +23,8 @@ namespace Ndk
inline void ChangeState(std::shared_ptr<State> state); inline void ChangeState(std::shared_ptr<State> state);
inline const std::shared_ptr<State>& GetCurrentState() const;
inline bool Update(float elapsedTime); inline bool Update(float elapsedTime);
inline StateMachine& operator=(StateMachine&& fsm) = default; inline StateMachine& operator=(StateMachine&& fsm) = default;

View File

@ -26,6 +26,11 @@ namespace Ndk
m_nextState = std::move(state); m_nextState = std::move(state);
} }
inline const std::shared_ptr<State>& StateMachine::GetCurrentState() const
{
return m_currentState;
}
inline bool StateMachine::Update(float elapsedTime) inline bool StateMachine::Update(float elapsedTime)
{ {
if (m_nextState) if (m_nextState)

View File

@ -1,16 +1,14 @@
// This file was automatically generated on 03 Mar 2016 at 14:09:12 // This file was automatically generated on 30 Jul 2016 at 15:29:16
#pragma once #pragma once
#ifndef NDK_SYSTEMS_GLOBAL_HPP #ifndef NDK_SYSTEMS_GLOBAL_HPP
#define NDK_SYSTEMS_GLOBAL_HPP #define NDK_SYSTEMS_GLOBAL_HPP
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/ParticleSystem.hpp>
#include <NDK/Systems/PhysicsSystem.hpp> #include <NDK/Systems/PhysicsSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#include <NDK/Systems/VelocitySystem.hpp> #include <NDK/Systems/VelocitySystem.hpp>
#ifndef NDK_SERVER
#include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp>
#endif
#endif // NDK_SYSTEMS_GLOBAL_HPP #endif // NDK_SYSTEMS_GLOBAL_HPP

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#ifndef NDK_SERVER
#ifndef NDK_SYSTEMS_LISTENERSYSTEM_HPP #ifndef NDK_SYSTEMS_LISTENERSYSTEM_HPP
#define NDK_SYSTEMS_LISTENERSYSTEM_HPP #define NDK_SYSTEMS_LISTENERSYSTEM_HPP
@ -27,3 +28,4 @@ namespace Ndk
#include <NDK/Systems/ListenerSystem.inl> #include <NDK/Systems/ListenerSystem.inl>
#endif // NDK_SYSTEMS_LISTENERSYSTEM_HPP #endif // NDK_SYSTEMS_LISTENERSYSTEM_HPP
#endif // NDK_SERVER

View File

@ -0,0 +1,29 @@
// 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
#pragma once
#ifndef NDK_SYSTEMS_PARTICLESYSTEM_HPP
#define NDK_SYSTEMS_PARTICLESYSTEM_HPP
#include <NDK/System.hpp>
namespace Ndk
{
class NDK_API ParticleSystem : public System<ParticleSystem>
{
public:
ParticleSystem();
~ParticleSystem() = default;
static SystemIndex systemIndex;
private:
void OnUpdate(float elapsedTime) override;
};
}
#include <NDK/Systems/ParticleSystem.inl>
#endif // NDK_SYSTEMS_PARTICLESYSTEM_HPP

View File

@ -0,0 +1,3 @@
// 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

View File

@ -4,11 +4,14 @@
#pragma once #pragma once
#ifndef NDK_SERVER
#ifndef NDK_SYSTEMS_RENDERSYSTEM_HPP #ifndef NDK_SYSTEMS_RENDERSYSTEM_HPP
#define NDK_SYSTEMS_RENDERSYSTEM_HPP #define NDK_SYSTEMS_RENDERSYSTEM_HPP
#include <Nazara/Graphics/AbstractBackground.hpp> #include <Nazara/Graphics/AbstractBackground.hpp>
#include <Nazara/Graphics/DeferredRenderTechnique.hpp> #include <Nazara/Graphics/DepthRenderTechnique.hpp>
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
#include <Nazara/Renderer/RenderTexture.hpp>
#include <NDK/EntityList.hpp> #include <NDK/EntityList.hpp>
#include <NDK/System.hpp> #include <NDK/System.hpp>
#include <unordered_map> #include <unordered_map>
@ -48,13 +51,20 @@ namespace Ndk
void OnEntityRemoved(Entity* entity) override; void OnEntityRemoved(Entity* entity) override;
void OnEntityValidation(Entity* entity, bool justAdded) override; void OnEntityValidation(Entity* entity, bool justAdded) override;
void OnUpdate(float elapsedTime) override; void OnUpdate(float elapsedTime) override;
void UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer);
void UpdatePointSpotShadowMaps();
std::unique_ptr<Nz::AbstractRenderTechnique> m_renderTechnique; std::unique_ptr<Nz::AbstractRenderTechnique> m_renderTechnique;
EntityList m_cameras; EntityList m_cameras;
EntityList m_drawables; EntityList m_drawables;
EntityList m_directionalLights;
EntityList m_lights; EntityList m_lights;
EntityList m_pointSpotLights;
EntityList m_particleGroups;
Nz::BackgroundRef m_background; Nz::BackgroundRef m_background;
Nz::DepthRenderTechnique m_shadowTechnique;
Nz::Matrix4f m_coordinateSystemMatrix; Nz::Matrix4f m_coordinateSystemMatrix;
Nz::RenderTexture m_shadowRT;
bool m_coordinateSystemInvalidated; bool m_coordinateSystemInvalidated;
}; };
} }
@ -62,3 +72,4 @@ namespace Ndk
#include <NDK/Systems/RenderSystem.inl> #include <NDK/Systems/RenderSystem.inl>
#endif // NDK_SYSTEMS_RENDERSYSTEM_HPP #endif // NDK_SYSTEMS_RENDERSYSTEM_HPP
#endif // NDK_SERVER

View File

@ -44,7 +44,7 @@ namespace Ndk
static_assert(std::is_base_of<BaseSystem, SystemType>::value, "SystemType is not a component"); static_assert(std::is_base_of<BaseSystem, SystemType>::value, "SystemType is not a component");
// Allocation et affectation du component // Allocation et affectation du component
std::unique_ptr<SystemType> ptr(new SystemType(std::forward(args)...)); std::unique_ptr<SystemType> ptr(new SystemType(std::forward<Args>(args)...));
return static_cast<SystemType&>(AddSystem(std::move(ptr))); return static_cast<SystemType&>(AddSystem(std::move(ptr)));
} }

View File

@ -9,7 +9,7 @@
namespace Ndk namespace Ndk
{ {
void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index) void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index)
{ {
NazaraAssert(index < m_renderables.size(), "Invalid renderable index"); NazaraAssert(index < m_renderables.size(), "Invalid renderable index");
NazaraUnused(renderable); NazaraUnused(renderable);

View File

@ -0,0 +1,17 @@
// 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/ParticleEmitterComponent.hpp>
#include <Nazara/Graphics/ParticleGroup.hpp>
namespace Ndk
{
void ParticleEmitterComponent::SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const
{
if (m_isActive && m_setupFunc)
m_setupFunc(m_entity, mapper, count);
}
ComponentIndex ParticleEmitterComponent::componentIndex;
}

View File

@ -0,0 +1,10 @@
// 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>
namespace Ndk
{
ComponentIndex ParticleGroupComponent::componentIndex;
}

View File

@ -28,8 +28,8 @@ namespace Ndk
m_characterSize(24) m_characterSize(24)
{ {
Nz::MaterialRef backgroundMaterial = Nz::Material::New(); Nz::MaterialRef backgroundMaterial = Nz::Material::New();
backgroundMaterial->Enable(Nz::RendererParameter_Blend, true); backgroundMaterial->EnableBlending(true);
backgroundMaterial->Enable(Nz::RendererParameter_DepthBuffer, false); backgroundMaterial->EnableDepthBuffer(false);
backgroundMaterial->SetDstBlend(Nz::BlendFunc_InvSrcAlpha); backgroundMaterial->SetDstBlend(Nz::BlendFunc_InvSrcAlpha);
backgroundMaterial->SetSrcBlend(Nz::BlendFunc_SrcAlpha); backgroundMaterial->SetSrcBlend(Nz::BlendFunc_SrcAlpha);
@ -145,6 +145,7 @@ namespace Ndk
{ {
case Nz::Keyboard::Down: case Nz::Keyboard::Down:
case Nz::Keyboard::Up: case Nz::Keyboard::Up:
{
if (event.key.code == Nz::Keyboard::Up) if (event.key.code == Nz::Keyboard::Up)
m_historyPosition = std::min<std::size_t>(m_commandHistory.size(), m_historyPosition + 1); m_historyPosition = std::min<std::size_t>(m_commandHistory.size(), m_historyPosition + 1);
else else
@ -160,6 +161,10 @@ namespace Ndk
m_inputTextSprite->Update(m_inputDrawer); m_inputTextSprite->Update(m_inputDrawer);
break; break;
} }
default:
break;
}
break; break;
} }
} }

View File

@ -51,7 +51,7 @@ namespace Ndk
BaseComponent& component = *m_components[index].get(); BaseComponent& component = *m_components[index].get();
component.SetEntity(this); component.SetEntity(this);
for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
{ {
if (i != index) if (i != index)
m_components[i]->OnComponentAttached(component); m_components[i]->OnComponentAttached(component);
@ -73,8 +73,8 @@ namespace Ndk
void Entity::RemoveAllComponents() void Entity::RemoveAllComponents()
{ {
for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
RemoveComponent(i); RemoveComponent(static_cast<ComponentIndex>(i));
NazaraAssert(m_componentBits.TestNone(), "All components should be gone"); NazaraAssert(m_componentBits.TestNone(), "All components should be gone");
@ -90,7 +90,7 @@ namespace Ndk
{ {
// On récupère le component et on informe les composants du détachement // On récupère le component et on informe les composants du détachement
BaseComponent& component = *m_components[index].get(); BaseComponent& component = *m_components[index].get();
for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i))
{ {
if (i != index) if (i != index)
m_components[i]->OnComponentDetached(component); m_components[i]->OnComponentDetached(component);
@ -114,7 +114,7 @@ namespace Ndk
void Entity::Destroy() void Entity::Destroy()
{ {
// On informe chaque système // On informe chaque système
for (SystemIndex index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) for (std::size_t index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index))
{ {
if (m_world->HasSystem(index)) if (m_world->HasSystem(index))
{ {

View File

@ -29,8 +29,8 @@ namespace Ndk
// SDK // SDK
application("Application"), application("Application"),
nodeComponent("NodeComponent"),
entityClass("Entity"), entityClass("Entity"),
nodeComponent("NodeComponent"),
velocityComponent("VelocityComponent"), velocityComponent("VelocityComponent"),
worldClass("World") worldClass("World")
@ -39,9 +39,9 @@ namespace Ndk
// Audio // Audio
musicClass("Music"), musicClass("Music"),
soundClass("Sound"),
soundBuffer("SoundBuffer"), soundBuffer("SoundBuffer"),
soundEmitter("SoundEmitter"), soundEmitter("SoundEmitter"),
soundClass("Sound"),
// Graphics // Graphics
instancedRenderable("InstancedRenderable"), instancedRenderable("InstancedRenderable"),

View File

@ -76,6 +76,8 @@ namespace Ndk
/*********************************** Nz::SoundBuffer **********************************/ /*********************************** Nz::SoundBuffer **********************************/
soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance) soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance)
{ {
NazaraUnused(lua);
Nz::PlacementNew(instance, Nz::SoundBuffer::New()); Nz::PlacementNew(instance, Nz::SoundBuffer::New());
return true; return true;
}); });
@ -115,16 +117,16 @@ namespace Ndk
return 1; return 1;
}); });
soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int
{ {
Nz::StringStream stream("SoundBuffer("); Nz::StringStream stream("SoundBuffer(");
if (soundBuffer->IsValid()) if (instance->IsValid())
{ {
Nz::String filePath = soundBuffer->GetFilePath(); Nz::String filePath = instance->GetFilePath();
if (!filePath.IsEmpty()) if (!filePath.IsEmpty())
stream << "File: " << filePath << ", "; stream << "File: " << filePath << ", ";
stream << "Duration: " << soundBuffer->GetDuration() / 1000.f << "s"; stream << "Duration: " << instance->GetDuration() / 1000.f << "s";
} }
stream << ')'; stream << ')';

View File

@ -205,7 +205,7 @@ namespace Ndk
{ {
case Nz::LuaType_Number: case Nz::LuaType_Number:
{ {
long long index = lua.CheckInteger(1); auto index = lua.CheckBoundInteger<std::size_t>(1);
if (index < 1 || index > 4) if (index < 1 || index > 4)
return false; return false;
@ -238,9 +238,15 @@ namespace Ndk
case 'h': case 'h':
lua.Push(instance.height); lua.Push(instance.height);
return true; return true;
default:
break;
} }
break; break;
} }
default:
break;
} }
return false; return false;
@ -252,7 +258,7 @@ namespace Ndk
{ {
case Nz::LuaType_Number: case Nz::LuaType_Number:
{ {
long long index = lua.CheckInteger(1); auto index = lua.CheckBoundInteger<std::size_t>(1);
if (index < 1 || index > 4) if (index < 1 || index > 4)
return false; return false;
@ -290,6 +296,9 @@ namespace Ndk
} }
break; break;
} }
default:
break;
} }
return false; return false;
@ -389,6 +398,9 @@ namespace Ndk
case 'z': case 'z':
instance.z = value; instance.z = value;
return true; return true;
default:
break;
} }
return false; return false;
@ -455,9 +467,15 @@ namespace Ndk
case 'y': case 'y':
lua.Push(instance.y); lua.Push(instance.y);
return true; return true;
default:
break;
} }
break; break;
} }
default:
break;
} }
return false; return false;
@ -496,9 +514,15 @@ namespace Ndk
case 'y': case 'y':
instance.y = value; instance.y = value;
return true; return true;
default:
break;
} }
break; break;
} }
default:
break;
} }
return false; return false;
@ -513,11 +537,12 @@ namespace Ndk
case 0: case 0:
case 3: case 3:
Nz::PlacementNew(vector, lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0), lua.CheckNumber(3, 0.0)); Nz::PlacementNew(vector, lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0), lua.CheckNumber(3, 0.0));
return true;
case 1: case 1:
{ {
if (lua.IsOfType(1, Nz::LuaType_Number)) if (lua.IsOfType(1, Nz::LuaType_Number))
Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast<Nz::Vector2d*>(lua.ToUserdata(1))); Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast<Nz::Vector2d*>(lua.CheckUserdata(1, "Vector2")));
else if (lua.IsOfType(1, "Vector2")) else if (lua.IsOfType(1, "Vector2"))
Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1))); Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1)));
else if (lua.IsOfType(1, "Vector3")) else if (lua.IsOfType(1, "Vector3"))
@ -582,9 +607,15 @@ namespace Ndk
case 'z': case 'z':
lua.Push(instance.z); lua.Push(instance.z);
return true; return true;
default:
break;
} }
break; break;
} }
default:
break;
} }
return false; return false;
@ -627,9 +658,15 @@ namespace Ndk
case 'z': case 'z':
instance.z = value; instance.z = value;
return true; return true;
default:
break;
} }
break; break;
} }
default:
break;
} }
return false; return false;

View File

@ -25,6 +25,9 @@
#include <NDK/Components/LightComponent.hpp> #include <NDK/Components/LightComponent.hpp>
#include <NDK/Components/ListenerComponent.hpp> #include <NDK/Components/ListenerComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/ParticleEmitterComponent.hpp>
#include <NDK/Components/ParticleGroupComponent.hpp>
#include <NDK/Systems/ParticleSystem.hpp>
#include <NDK/Systems/ListenerSystem.hpp> #include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp> #include <NDK/Systems/RenderSystem.hpp>
#endif #endif
@ -71,6 +74,8 @@ namespace Ndk
InitializeComponent<LightComponent>("NdkLight"); InitializeComponent<LightComponent>("NdkLight");
InitializeComponent<ListenerComponent>("NdkList"); InitializeComponent<ListenerComponent>("NdkList");
InitializeComponent<GraphicsComponent>("NdkGfx"); InitializeComponent<GraphicsComponent>("NdkGfx");
InitializeComponent<ParticleEmitterComponent>("NdkPaEmi");
InitializeComponent<ParticleGroupComponent>("NdkPaGrp");
#endif #endif
// Systems // Systems
@ -84,6 +89,7 @@ namespace Ndk
#ifndef NDK_SERVER #ifndef NDK_SERVER
// Client systems // Client systems
InitializeSystem<ListenerSystem>(); InitializeSystem<ListenerSystem>();
InitializeSystem<ParticleSystem>();
InitializeSystem<RenderSystem>(); InitializeSystem<RenderSystem>();
#endif #endif
@ -112,6 +118,12 @@ namespace Ndk
// Uninitialize the SDK // Uninitialize the SDK
s_referenceCounter = 0; s_referenceCounter = 0;
// Components
BaseComponent::Uninitialize();
// Systems
BaseSystem::Uninitialize();
// Uninitialize the engine // Uninitialize the engine
#ifndef NDK_SERVER #ifndef NDK_SERVER

10
SDK/src/NDK/State.cpp Normal file
View File

@ -0,0 +1,10 @@
// Copyright (C) 2016 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/State.hpp>
namespace Ndk
{
State::~State() = default;
}

View File

@ -0,0 +1,26 @@
// 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/Systems/ParticleSystem.hpp>
#include <NDK/Components/ParticleGroupComponent.hpp>
namespace Ndk
{
ParticleSystem::ParticleSystem()
{
Requires<ParticleGroupComponent>();
}
void ParticleSystem::OnUpdate(float elapsedTime)
{
for (const Ndk::EntityHandle& entity : GetEntities())
{
ParticleGroupComponent& group = entity->GetComponent<ParticleGroupComponent>();
group.Update(elapsedTime);
}
}
SystemIndex ParticleSystem::systemIndex;
}

View File

@ -4,10 +4,13 @@
#include <NDK/Systems/RenderSystem.hpp> #include <NDK/Systems/RenderSystem.hpp>
#include <Nazara/Graphics/ColorBackground.hpp> #include <Nazara/Graphics/ColorBackground.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <NDK/Components/CameraComponent.hpp> #include <NDK/Components/CameraComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/LightComponent.hpp> #include <NDK/Components/LightComponent.hpp>
#include <NDK/Components/NodeComponent.hpp> #include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/ParticleGroupComponent.hpp>
namespace Ndk namespace Ndk
{ {
@ -23,8 +26,11 @@ namespace Ndk
void RenderSystem::OnEntityRemoved(Entity* entity) void RenderSystem::OnEntityRemoved(Entity* entity)
{ {
m_cameras.Remove(entity); m_cameras.Remove(entity);
m_directionalLights.Remove(entity);
m_drawables.Remove(entity); m_drawables.Remove(entity);
m_lights.Remove(entity); m_lights.Remove(entity);
m_particleGroups.Remove(entity);
m_pointSpotLights.Remove(entity);
} }
void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded) void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded)
@ -48,9 +54,32 @@ namespace Ndk
m_drawables.Remove(entity); m_drawables.Remove(entity);
if (entity->HasComponent<LightComponent>() && entity->HasComponent<NodeComponent>()) if (entity->HasComponent<LightComponent>() && entity->HasComponent<NodeComponent>())
m_lights.Insert(entity); {
LightComponent& lightComponent = entity->GetComponent<LightComponent>();
if (lightComponent.GetLightType() == Nz::LightType_Directional)
{
m_directionalLights.Insert(entity);
m_pointSpotLights.Remove(entity);
}
else else
{
m_directionalLights.Remove(entity);
m_pointSpotLights.Insert(entity);
}
m_lights.Insert(entity);
}
else
{
m_directionalLights.Remove(entity);
m_lights.Remove(entity); m_lights.Remove(entity);
m_pointSpotLights.Remove(entity);
}
if (entity->HasComponent<ParticleGroupComponent>())
m_particleGroups.Insert(entity);
else
m_particleGroups.Remove(entity);
} }
void RenderSystem::OnUpdate(float elapsedTime) void RenderSystem::OnUpdate(float elapsedTime)
@ -69,10 +98,13 @@ namespace Ndk
m_coordinateSystemInvalidated = false; m_coordinateSystemInvalidated = false;
} }
UpdatePointSpotShadowMaps();
for (const Ndk::EntityHandle& camera : m_cameras) for (const Ndk::EntityHandle& camera : m_cameras)
{ {
CameraComponent& camComponent = camera->GetComponent<CameraComponent>(); CameraComponent& camComponent = camera->GetComponent<CameraComponent>();
camComponent.ApplyView();
//UpdateDirectionalShadowMaps(camComponent);
Nz::AbstractRenderQueue* renderQueue = m_renderTechnique->GetRenderQueue(); Nz::AbstractRenderQueue* renderQueue = m_renderTechnique->GetRenderQueue();
renderQueue->Clear(); renderQueue->Clear();
@ -89,12 +121,21 @@ namespace Ndk
for (const Ndk::EntityHandle& light : m_lights) for (const Ndk::EntityHandle& light : m_lights)
{ {
LightComponent& lightComponent = light->GetComponent<LightComponent>(); LightComponent& lightComponent = light->GetComponent<LightComponent>();
NodeComponent& drawableNode = light->GetComponent<NodeComponent>(); NodeComponent& lightNode = light->GetComponent<NodeComponent>();
///TODO: Cache somehow? ///TODO: Cache somehow?
lightComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::ConcatenateAffine(m_coordinateSystemMatrix, drawableNode.GetTransformMatrix())); lightComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::ConcatenateAffine(m_coordinateSystemMatrix, lightNode.GetTransformMatrix()));
} }
for (const Ndk::EntityHandle& particleGroup : m_particleGroups)
{
ParticleGroupComponent& groupComponent = particleGroup->GetComponent<ParticleGroupComponent>();
groupComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::Identity()); //< ParticleGroup doesn't use Matrix4f
}
camComponent.ApplyView();
Nz::SceneData sceneData; Nz::SceneData sceneData;
sceneData.ambientColor = Nz::Color(25, 25, 25); sceneData.ambientColor = Nz::Color(25, 25, 25);
sceneData.background = m_background; sceneData.background = m_background;
@ -105,5 +146,146 @@ namespace Ndk
} }
} }
void RenderSystem::UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer)
{
if (!m_shadowRT.IsValid())
m_shadowRT.Create();
Nz::SceneData dummySceneData;
dummySceneData.ambientColor = Nz::Color(0, 0, 0);
dummySceneData.background = nullptr;
dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer
for (const Ndk::EntityHandle& light : m_directionalLights)
{
LightComponent& lightComponent = light->GetComponent<LightComponent>();
NodeComponent& lightNode = light->GetComponent<NodeComponent>();
if (!lightComponent.IsShadowCastingEnabled())
continue;
Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize());
m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap());
Nz::Renderer::SetTarget(&m_shadowRT);
Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y));
Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue();
renderQueue->Clear();
///TODO: Culling
for (const Ndk::EntityHandle& drawable : m_drawables)
{
GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>();
NodeComponent& drawableNode = drawable->GetComponent<NodeComponent>();
graphicsComponent.AddToRenderQueue(renderQueue);
}
///TODO: Cache the matrices in the light?
Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f));
Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetRotation() * Nz::Vector3f::Forward() * 100.f, lightNode.GetRotation()));
m_shadowTechnique.Clear(dummySceneData);
m_shadowTechnique.Draw(dummySceneData);
}
}
void RenderSystem::UpdatePointSpotShadowMaps()
{
if (!m_shadowRT.IsValid())
m_shadowRT.Create();
Nz::SceneData dummySceneData;
dummySceneData.ambientColor = Nz::Color(0, 0, 0);
dummySceneData.background = nullptr;
dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer
for (const Ndk::EntityHandle& light : m_pointSpotLights)
{
LightComponent& lightComponent = light->GetComponent<LightComponent>();
NodeComponent& lightNode = light->GetComponent<NodeComponent>();
if (!lightComponent.IsShadowCastingEnabled())
continue;
Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize());
switch (lightComponent.GetLightType())
{
case Nz::LightType_Directional:
NazaraInternalError("Directional lights included in point/spot light list");
break;
case Nz::LightType_Point:
{
static Nz::Quaternionf rotations[6] =
{
Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitX()), // nzCubemapFace_PositiveX
Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitX()), // nzCubemapFace_NegativeX
Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitY()), // nzCubemapFace_PositiveY
Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitY()), // nzCubemapFace_NegativeY
Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitZ()), // nzCubemapFace_PositiveZ
Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitZ()) // nzCubemapFace_NegativeZ
};
for (unsigned int face = 0; face < 6; ++face)
{
m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap(), face);
Nz::Renderer::SetTarget(&m_shadowRT);
Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y));
///TODO: Cache the matrices in the light?
Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(Nz::FromDegrees(90.f), 1.f, 0.1f, lightComponent.GetRadius()));
Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), rotations[face]));
Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue();
renderQueue->Clear();
///TODO: Culling
for (const Ndk::EntityHandle& drawable : m_drawables)
{
GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>();
NodeComponent& drawableNode = drawable->GetComponent<NodeComponent>();
graphicsComponent.AddToRenderQueue(renderQueue);
}
m_shadowTechnique.Clear(dummySceneData);
m_shadowTechnique.Draw(dummySceneData);
}
break;
}
case Nz::LightType_Spot:
{
m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap());
Nz::Renderer::SetTarget(&m_shadowRT);
Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y));
///TODO: Cache the matrices in the light?
Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(lightComponent.GetOuterAngle()*2.f, 1.f, 0.1f, lightComponent.GetRadius()));
Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation()));
Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue();
renderQueue->Clear();
///TODO: Culling
for (const Ndk::EntityHandle& drawable : m_drawables)
{
GraphicsComponent& graphicsComponent = drawable->GetComponent<GraphicsComponent>();
NodeComponent& drawableNode = drawable->GetComponent<NodeComponent>();
graphicsComponent.AddToRenderQueue(renderQueue);
}
m_shadowTechnique.Clear(dummySceneData);
m_shadowTechnique.Draw(dummySceneData);
break;
}
}
}
}
SystemIndex RenderSystem::systemIndex; SystemIndex RenderSystem::systemIndex;
} }

View File

@ -22,7 +22,7 @@ namespace Ndk
NodeComponent& node = entity->GetComponent<NodeComponent>(); NodeComponent& node = entity->GetComponent<NodeComponent>();
const VelocityComponent& velocity = entity->GetComponent<VelocityComponent>(); const VelocityComponent& velocity = entity->GetComponent<VelocityComponent>();
node.Move(velocity.linearVelocity * elapsedTime); node.Move(velocity.linearVelocity * elapsedTime, Nz::CoordSys_Global);
} }
} }

View File

@ -9,6 +9,7 @@
#ifndef NDK_SERVER #ifndef NDK_SERVER
#include <NDK/Systems/ListenerSystem.hpp> #include <NDK/Systems/ListenerSystem.hpp>
#include <NDK/Systems/ParticleSystem.hpp>
#include <NDK/Systems/RenderSystem.hpp> #include <NDK/Systems/RenderSystem.hpp>
#endif #endif
@ -27,6 +28,7 @@ namespace Ndk
#ifndef NDK_SERVER #ifndef NDK_SERVER
AddSystem<ListenerSystem>(); AddSystem<ListenerSystem>();
AddSystem<ParticleSystem>();
AddSystem<RenderSystem>(); AddSystem<RenderSystem>();
#endif #endif
} }
@ -94,7 +96,7 @@ namespace Ndk
void World::Update() void World::Update()
{ {
// Gestion des entités tuées depuis le dernier appel // Gestion des entités tuées depuis le dernier appel
for (unsigned int i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i)) for (std::size_t i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i))
{ {
EntityBlock& block = m_entities[i]; EntityBlock& block = m_entities[i];
Entity& entity = block.entity; Entity& entity = block.entity;
@ -127,7 +129,7 @@ namespace Ndk
m_killedEntities.Reset(); m_killedEntities.Reset();
// Gestion des entités nécessitant une mise à jour de leurs systèmes // Gestion des entités nécessitant une mise à jour de leurs systèmes
for (unsigned int i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i)) for (std::size_t i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i))
{ {
NazaraAssert(i < m_entities.size(), "Entity index out of range"); NazaraAssert(i < m_entities.size(), "Entity index out of range");

View File

@ -1 +1 @@
premake4 --with-extlibs --with-examples codeblocks premake4 codeblocks

View File

@ -1 +0,0 @@
premake4 --united --with-extlibs --with-examples codeblocks

View File

@ -1 +1 @@
premake5 --with-extlibs --with-examples codelite premake5 codelite

View File

@ -1 +0,0 @@
premake5 --united --with-extlibs --with-examples codelite

View File

@ -1 +1 @@
premake5 --with-extlibs --with-examples vs2015 premake5 vs2015

View File

@ -1 +0,0 @@
premake5 --united --with-extlibs --with-examples vs2015

17
build/config.lua Normal file
View File

@ -0,0 +1,17 @@
-- This file contains special configurations values, such as directories to extern libraries (Qt)
-- Editing this file is not required to use/compile the engine, as default values should be enough
-- Builds Nazara extern libraries (such as lua/STB)
BuildDependencies = true
-- Builds Nazara examples
BuildExamples = true
-- Setup additionnals install directories, separated by a semi-colon ; (library binaries will be copied there)
--InstallDir = "/usr/local/lib64"
-- Excludes client-only modules/tools/examples
ServerMode = false
-- Builds modules as one united library (useless on POSIX systems)
UniteModules = false

View File

@ -1,16 +1,32 @@
NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table
function NazaraBuild:AddExecutablePath(path)
self.ExecutableDir[path] = true
self.InstallDir[path] = true
end
function NazaraBuild:AddInstallPath(path)
self.InstallDir[path] = true
end
function NazaraBuild:Execute() function NazaraBuild:Execute()
if (_ACTION == nil) then -- Si aucune action n'est spécifiée if (_ACTION == nil) then -- Si aucune action n'est spécifiée
return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien
end end
local platformData
if (os.is64bit()) then
platformData = {"x64", "x32"}
else
platformData = {"x32", "x64"}
end
if (self.Actions[_ACTION] == nil) then if (self.Actions[_ACTION] == nil) then
local makeLibDir = os.is("windows") and "mingw" or "gmake" local makeLibDir = os.is("windows") and "mingw" or "gmake"
if (#self.OrderedExtLibs > 0) then if (self.Config["BuildDependencies"]) then
workspace("NazaraExtlibs") workspace("NazaraExtlibs")
platforms({"x32", "x64"}) platforms(platformData)
-- Configuration générale -- Configuration générale
configurations({ configurations({
@ -23,12 +39,6 @@ function NazaraBuild:Execute()
location(_ACTION) location(_ACTION)
kind("StaticLib") kind("StaticLib")
configuration("x32")
libdirs("../extlibs/lib/common/x86")
configuration("x64")
libdirs("../extlibs/lib/common/x64")
configuration({"codeblocks or codelite or gmake", "x32"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") targetdir("../extlibs/lib/" .. makeLibDir .. "/x86")
@ -38,7 +48,7 @@ function NazaraBuild:Execute()
targetdir("../extlibs/lib/" .. makeLibDir .. "/x64") targetdir("../extlibs/lib/" .. makeLibDir .. "/x64")
configuration("vs*") configuration("vs*")
buildoptions("/MP") buildoptions({"/MP", "/bigobj"}) -- Multiprocessus build and big .obj
configuration({"vs*", "x32"}) configuration({"vs*", "x32"})
libdirs("../extlibs/lib/msvc/x86") libdirs("../extlibs/lib/msvc/x86")
@ -75,8 +85,11 @@ function NazaraBuild:Execute()
configuration("ReleaseStatic") configuration("ReleaseStatic")
targetsuffix("-s") targetsuffix("-s")
configuration({"not windows", "codeblocks or codelite or gmake or xcode3 or xcode4"})
buildoptions("-fPIC")
configuration("codeblocks or codelite or gmake or xcode3 or xcode4") configuration("codeblocks or codelite or gmake or xcode3 or xcode4")
buildoptions({"-fPIC", "-std=c++14"}) buildoptions({"-std=c++14", "-U__STRICT_ANSI__"})
for k, libTable in ipairs(self.OrderedExtLibs) do for k, libTable in ipairs(self.OrderedExtLibs) do
project(libTable.Name) project(libTable.Name)
@ -92,6 +105,12 @@ function NazaraBuild:Execute()
includedirs(libTable.Includes) includedirs(libTable.Includes)
links(libTable.Libraries) links(libTable.Libraries)
configuration("x32")
libdirs(libTable.LibraryPaths.x86)
configuration("x64")
libdirs(libTable.LibraryPaths.x64)
for k,v in pairs(libTable.ConfigurationLibraries) do for k,v in pairs(libTable.ConfigurationLibraries) do
configuration(k) configuration(k)
links(v) links(v)
@ -102,7 +121,7 @@ function NazaraBuild:Execute()
end end
workspace("NazaraEngine") workspace("NazaraEngine")
platforms({"x32", "x64"}) platforms(platformData)
-- Configuration générale -- Configuration générale
configurations({ configurations({
@ -138,11 +157,8 @@ function NazaraBuild:Execute()
configuration({"linux or bsd or macosx", "gmake"}) configuration({"linux or bsd or macosx", "gmake"})
buildoptions("-fvisibility=hidden") buildoptions("-fvisibility=hidden")
configuration({"linux or bsd or macosx", "gmake"})
buildoptions("-fvisibility=hidden")
configuration("vs*") configuration("vs*")
buildoptions("/MP") -- Multiprocessus build buildoptions({"/MP", "/bigobj"}) -- Multiprocessus build and big .obj
flags("NoMinimalRebuild") flags("NoMinimalRebuild")
defines("_CRT_SECURE_NO_WARNINGS") defines("_CRT_SECURE_NO_WARNINGS")
defines("_SCL_SECURE_NO_WARNINGS") defines("_SCL_SECURE_NO_WARNINGS")
@ -172,11 +188,11 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/common") libdirs("../extlibs/lib/common")
configuration("x32") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs(moduleTable.LibraryPaths.x86)
configuration("x64") configuration("x64")
defines("NAZARA_PLATFORM_x64") defines("NAZARA_PLATFORM_x64")
libdirs("../extlibs/lib/common/x64") libdirs(moduleTable.LibraryPaths.x64)
configuration({"codeblocks or codelite or gmake", "x32"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
@ -188,6 +204,9 @@ function NazaraBuild:Execute()
libdirs("../lib/" .. makeLibDir .. "/x64") libdirs("../lib/" .. makeLibDir .. "/x64")
targetdir("../lib/" .. makeLibDir .. "/x64") targetdir("../lib/" .. makeLibDir .. "/x64")
-- Copy the module binaries to the example folder
self:MakeInstallCommands(moduleTable)
configuration({"vs*", "x32"}) configuration({"vs*", "x32"})
libdirs("../extlibs/lib/msvc/x86") libdirs("../extlibs/lib/msvc/x86")
libdirs("../lib/msvc/x86") libdirs("../lib/msvc/x86")
@ -251,16 +270,20 @@ function NazaraBuild:Execute()
project(prefix .. toolTable.Name) project(prefix .. toolTable.Name)
location(_ACTION .. "/tools") location(_ACTION .. "/tools")
targetdir(toolTable.Directory) targetdir(toolTable.TargetDirectory)
if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then
kind("SharedLib") kind("SharedLib")
elseif (toolTable.Kind == "consoleapp") then
debugdir(toolTable.Directory) -- Copy the tool binaries to the example folder
self:MakeInstallCommands(toolTable)
elseif (toolTable.Kind == "application") then
debugdir(toolTable.TargetDirectory)
if (toolTable.EnableConsole) then
kind("ConsoleApp") kind("ConsoleApp")
elseif (toolTable.Kind == "windowapp") then else
debugdir(toolTable.Directory)
kind("WindowedApp") kind("WindowedApp")
end
else else
assert(false, "Invalid tool Kind") assert(false, "Invalid tool Kind")
end end
@ -274,11 +297,11 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/common") libdirs("../extlibs/lib/common")
configuration("x32") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs(toolTable.LibraryPaths.x86)
configuration("x64") configuration("x64")
defines("NAZARA_PLATFORM_x64") defines("NAZARA_PLATFORM_x64")
libdirs("../extlibs/lib/common/x64") libdirs(toolTable.LibraryPaths.x64)
configuration({"codeblocks or codelite or gmake", "x32"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
@ -286,7 +309,7 @@ function NazaraBuild:Execute()
if (toolTable.Kind == "library") then if (toolTable.Kind == "library") then
targetdir("../lib/" .. makeLibDir .. "/x86") targetdir("../lib/" .. makeLibDir .. "/x86")
elseif (toolTable.Kind == "plugin") then elseif (toolTable.Kind == "plugin") then
targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x32") targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x86")
end end
configuration({"codeblocks or codelite or gmake", "x64"}) configuration({"codeblocks or codelite or gmake", "x64"})
@ -298,14 +321,6 @@ function NazaraBuild:Execute()
targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64") targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64")
end end
-- Copy the module binaries to the example folder
if (toolTable.CopyTargetToExampleDir) then
if (os.is("windows")) then
configuration({})
postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]})
end
end
configuration({"vs*", "x32"}) configuration({"vs*", "x32"})
libdirs("../extlibs/lib/msvc/x86") libdirs("../extlibs/lib/msvc/x86")
libdirs("../lib/msvc/x86") libdirs("../lib/msvc/x86")
@ -378,23 +393,34 @@ function NazaraBuild:Execute()
end end
for k, exampleTable in ipairs(self.OrderedExamples) do for k, exampleTable in ipairs(self.OrderedExamples) do
local destPath = "../examples/bin"
project("Demo" .. exampleTable.Name) project("Demo" .. exampleTable.Name)
location(_ACTION .. "/examples") location(_ACTION .. "/examples")
if (exampleTable.Console) then if (exampleTable.Kind == "plugin" or exampleTable.Kind == "library") then
kind("SharedLib")
self:MakeInstallCommands(toolTable)
elseif (exampleTable.Kind == "application") then
debugdir(exampleTable.TargetDirectory)
if (exampleTable.EnableConsole) then
kind("ConsoleApp") kind("ConsoleApp")
else else
kind("Window") kind("WindowedApp")
end
else
assert(false, "Invalid tool Kind")
end end
debugdir("../examples/bin") debugdir(destPath)
includedirs({ includedirs({
"../include", "../include",
"../extlibs/include" "../extlibs/include"
}) })
libdirs("../lib") libdirs("../lib")
targetdir("../examples/bin") targetdir(destPath)
files(exampleTable.Files) files(exampleTable.Files)
excludes(exampleTable.FilesExcluded) excludes(exampleTable.FilesExcluded)
@ -405,11 +431,11 @@ function NazaraBuild:Execute()
links(exampleTable.Libraries) links(exampleTable.Libraries)
configuration("x32") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs(exampleTable.LibraryPaths.x86)
configuration("x64") configuration("x64")
defines("NAZARA_PLATFORM_x64") defines("NAZARA_PLATFORM_x64")
libdirs("../extlibs/lib/common/x64") libdirs(exampleTable.LibraryPaths.x64)
configuration({"codeblocks or codelite or gmake", "x32"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86")
@ -439,29 +465,40 @@ function NazaraBuild:Execute()
end end
end end
function NazaraBuild:GetConfig()
return self.Config
end
function NazaraBuild:GetDependency(infoTable, name)
local projectName = name:match("Nazara(%w+)")
if (projectName) then
-- tool or module
local moduleTable = self.Modules[projectName:lower()]
if (moduleTable) then
return moduleTable
else
local toolTable = self.Tools[projectName:lower()]
if (toolTable) then
return toolTable
end
end
else
return self.ExtLibs[name:lower()]
end
end
function NazaraBuild:Initialize() function NazaraBuild:Initialize()
-- Commençons par les options
newoption({
trigger = "united",
description = "Builds all the modules as one united library"
})
newoption({
trigger = "with-extlibs",
description = "Builds the extern libraries"
})
newoption({
trigger = "with-examples",
description = "Builds the examples"
})
self.Actions = {} self.Actions = {}
self.Examples = {} self.Examples = {}
self.ExecutableDir = {}
self.ExtLibs = {} self.ExtLibs = {}
self.InstallDir = {}
self.Modules = {} self.Modules = {}
self.Tools = {} self.Tools = {}
self.Config = {}
self:LoadConfig()
-- Actions -- Actions
modules = os.matchfiles("scripts/actions/*.lua") modules = os.matchfiles("scripts/actions/*.lua")
for k,v in pairs(modules) do for k,v in pairs(modules) do
@ -482,13 +519,12 @@ function NazaraBuild:Initialize()
ACTION = nil ACTION = nil
-- Extern libraries -- Extern libraries
if (_OPTIONS["with-extlibs"]) then
local extlibs = os.matchfiles("../extlibs/build/*.lua") local extlibs = os.matchfiles("../extlibs/build/*.lua")
for k,v in pairs(extlibs) do for k,v in pairs(extlibs) do
local f, err = loadfile(v) local f, err = loadfile(v)
if (f) then if (f) then
LIBRARY = {} LIBRARY = {}
self:SetupInfoTable(LIBRARY) self:SetupExtlibTable(LIBRARY)
f() f()
@ -501,7 +537,6 @@ function NazaraBuild:Initialize()
end end
end end
LIBRARY = nil LIBRARY = nil
end
-- Then the modules -- Then the modules
local modules = os.matchfiles("scripts/modules/*.lua") local modules = os.matchfiles("scripts/modules/*.lua")
@ -509,18 +544,10 @@ function NazaraBuild:Initialize()
local moduleName = v:match(".*/(.*).lua") local moduleName = v:match(".*/(.*).lua")
local moduleNameLower = moduleName:lower() local moduleNameLower = moduleName:lower()
if (moduleNameLower ~= "core") then -- exclure le noyau n'aurait aucun sens
newoption({
trigger = "exclude-" .. moduleNameLower,
description = "Exclude the " .. moduleName .. " module from the build system"
})
end
if (not _OPTIONS["exclude-" .. moduleNameLower]) then
local f, err = loadfile(v) local f, err = loadfile(v)
if (f) then if (f) then
MODULE = {} MODULE = {}
self:SetupInfoTable(MODULE) self:SetupModuleTable(MODULE)
f() f()
@ -532,7 +559,6 @@ function NazaraBuild:Initialize()
print("Unable to load module file: " .. err) print("Unable to load module file: " .. err)
end end
end end
end
MODULE = nil MODULE = nil
-- Continue with the tools (ex: SDK) -- Continue with the tools (ex: SDK)
@ -541,16 +567,10 @@ function NazaraBuild:Initialize()
local toolName = v:match(".*/(.*).lua") local toolName = v:match(".*/(.*).lua")
local toolNameLower = toolName:lower() local toolNameLower = toolName:lower()
newoption({
trigger = "exclude-" .. toolNameLower,
description = "Exclude the " .. toolName .. " tool from the build system"
})
if (not _OPTIONS["exclude-" .. toolNameLower]) then
local f, err = loadfile(v) local f, err = loadfile(v)
if (f) then if (f) then
TOOL = {} TOOL = {}
self:SetupInfoTable(TOOL) self:SetupToolTable(TOOL)
f() f()
@ -562,11 +582,10 @@ function NazaraBuild:Initialize()
print("Unable to load tool file: " .. err) print("Unable to load tool file: " .. err)
end end
end end
end
TOOL = nil TOOL = nil
-- Examples -- Examples
if (_OPTIONS["with-examples"]) then if (self.Config["BuildExamples"]) then
local examples = os.matchdirs("../examples/*") local examples = os.matchdirs("../examples/*")
for k,v in pairs(examples) do for k,v in pairs(examples) do
local dirName = v:match(".*/(.*)") local dirName = v:match(".*/(.*)")
@ -575,7 +594,7 @@ function NazaraBuild:Initialize()
if (f) then if (f) then
EXAMPLE = {} EXAMPLE = {}
EXAMPLE.Directory = dirName EXAMPLE.Directory = dirName
self:SetupInfoTable(EXAMPLE) self:SetupExampleTable(EXAMPLE)
f() f()
@ -596,19 +615,255 @@ function NazaraBuild:Initialize()
self.OrderedExtLibs = {} self.OrderedExtLibs = {}
self.OrderedModules = {} self.OrderedModules = {}
self.OrderedTools = {} self.OrderedTools = {}
local tables = {self.Examples, self.ExtLibs, self.Modules, self.Tools} local tables = {self.ExtLibs, self.Modules, self.Tools, self.Examples}
local orderedTables = {self.OrderedExamples, self.OrderedExtLibs, self.OrderedModules, self.OrderedTools} local orderedTables = {self.OrderedExtLibs, self.OrderedModules, self.OrderedTools, self.OrderedExamples}
for k,projects in ipairs(tables) do for k,projects in ipairs(tables) do
-- Begin by resolving every project (because of dependencies in the same category)
for projectId,projectTable in pairs(projects) do for projectId,projectTable in pairs(projects) do
self:Process(projectTable) self:Resolve(projectTable)
end
for projectId,projectTable in pairs(projects) do
if (self:Process(projectTable)) then
table.insert(orderedTables[k], projectTable) table.insert(orderedTables[k], projectTable)
else
print("Rejected " .. projectTable.Name .. " " .. string.lower(projectTable.Type) .. ": " .. projectTable.ExcludeReason)
end
end end
table.sort(orderedTables[k], function (a, b) return a.Name < b.Name end) table.sort(orderedTables[k], function (a, b) return a.Name < b.Name end)
end end
end end
function NazaraBuild:LoadConfig()
local f = io.open("config.lua", "r")
if (f) then
local content = f:read("*a")
f:close()
local func, err = loadstring(content)
if (func) then
setfenv(func, self.Config)
local status, err = pcall(func)
if (not status) then
print("Failed to load config.lua: " .. err)
end
else
print("Failed to parse config.lua: " .. err)
end
else
print("Failed to open config.lua")
end
local configTable = self.Config
local AddBoolOption = function (option, name, description)
newoption({
trigger = name,
description = description
})
local str = _OPTIONS[name]
if (str) then
if (#str == 0 or str == "1" or str == "yes" or str == "true") then
configTable[option] = true
elseif (str == "0" or str == "no" or str == "false") then
configTable[option] = false
else
error("Invalid entry for " .. name .. " option: \"" .. str .. "\"")
end
end
end
AddBoolOption("BuildDependencies", "with-extlibs", "Builds the extern libraries")
AddBoolOption("BuildExamples", "with-examples", "Builds the examples")
AddBoolOption("ServerMode", "server", "Excludes client-only modules/tools/examples")
AddBoolOption("UniteModules", "united", "Builds all the modules as one united library")
-- InstallDir
newoption({
trigger = "install-path",
description = "Setup additionnals install directories (library binaries will be copied there)"
})
self.Config["InstallDir"] = self.Config["InstallDir"] or ""
if (_OPTIONS["install-path"] ~= nil) then
self.Config["InstallDir"] = self.Config["InstallDir"] .. ";" .. _OPTIONS["install-path"]
end
local paths = string.explode(self.Config["InstallDir"], ";")
for k,v in pairs(paths) do
if (#v > 0) then
self:AddInstallPath(v)
end
end
end
function NazaraBuild:MakeInstallCommands(infoTable)
if (PremakeVersion < 50) then
return
end
if (os.is("windows")) then
configuration({})
for k,v in pairs(self.InstallDir) do
local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k)
postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "]] .. destPath .. [[\" /E /Y]]})
end
for k,fileName in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do
local paths = {}
for k,v in pairs(infoTable.BinaryPaths.x86) do
table.insert(paths, {"x32", v .. "/" .. fileName .. ".dll"})
table.insert(paths, {"x32", v .. "/lib" .. fileName .. ".dll"})
end
for k,v in pairs(infoTable.BinaryPaths.x64) do
table.insert(paths, {"x64", v .. "/" .. fileName .. ".dll"})
table.insert(paths, {"x64", v .. "/lib" .. fileName .. ".dll"})
end
for k,v in pairs(paths) do
local config = v[1]
local srcPath = v[2]
if (os.isfile(srcPath)) then
if (infoTable.Kind == "plugin") then
srcPath = "../../" .. srcPath
end
configuration(config)
for k,v in pairs(self.ExecutableDir) do
local srcPath = path.isabsolute(srcPath) and path.translate(srcPath) or [[%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. srcPath .. [[")}]]
local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k)
postbuildcommands({[[xcopy "]] .. srcPath .. [[" "]] .. destPath .. [[\" /E /Y]]})
end
end
end
end
end
end
local PosixOSes = {
["bsd"] = true,
["linux"] = true,
["macosx"] = true,
["solaris"] = true
}
function NazaraBuild:Process(infoTable)
local libraries = {}
for k, library in pairs(infoTable.Libraries) do
local libraryTable = self:GetDependency(infoTable, library)
if (libraryTable) then
if (libraryTable.Excluded) then
infoTable.Excluded = true
infoTable.ExcludeReason = "depends on excluded " .. library .. " " .. libraryTable.Type:lower()
return false
end
if (libraryTable.Type == "Module") then
if (_OPTIONS["united"]) then
library = "NazaraEngine"
else
library = "Nazara" .. libraryTable.Name
end
if (not self.Config["UniteModules"] or infoTable.Type ~= "Module") then
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library)
end
elseif (libraryTable.Type == "ExternLib") then
library = libraryTable.Name
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s")
elseif (libraryTable.Type == "Tool") then
library = "Nazara" .. libraryTable.Name
-- Import tools includes
for k,v in ipairs(libraryTable.Includes) do
table.insert(infoTable.Includes, v)
end
-- And libraries
for k, v in pairs(libraryTable.Libraries) do
table.insert(infoTable.Libraries, v)
end
for config, libs in pairs(libraryTable.ConfigurationLibraries) do
for k,v in pairs(libs) do
table.insert(infoTable.ConfigurationLibraries[config], v)
end
end
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library)
else
infoTable.Excluded = true
infoTable.ExcludeReason = "dependency " .. library .. " has invalid type \"" .. libraryTable.Type .. "\""
return false
end
else
table.insert(libraries, library)
end
end
infoTable.Libraries = libraries
for k,v in pairs(infoTable) do
local target = k:match("Os(%w+)")
if (target) then
local targetTable = infoTable[target]
if (targetTable) then
local excludeTargetTable = infoTable[target .. "Excluded"]
for platform, defineTable in pairs(v) do
platform = string.lower(platform)
if (platform == "posix") then
local osname = os.get()
if (PosixOSes[osname]) then
platform = osname
end
end
if (os.is(platform)) then
for k,v in ipairs(defineTable) do
table.insert(targetTable, v)
end
elseif (excludeTargetTable) then
for k,v in ipairs(defineTable) do
table.insert(excludeTargetTable, v)
end
end
end
infoTable[k] = nil
end
end
end
if (infoTable.Kind == "application") then
self:AddExecutablePath(infoTable.TargetDirectory)
end
if (infoTable.Validate) then
local ret, err = infoTable:Validate()
if (not ret) then
infoTable.Excluded = true
infoTable.ExcludeReason = "validation failed: " .. err
return false
end
end
return true
end
function NazaraBuild:RegisterAction(actionTable) function NazaraBuild:RegisterAction(actionTable)
if (actionTable.Name == nil or type(actionTable.Name) ~= "string" or string.len(actionTable.Name) == 0) then if (actionTable.Name == nil or type(actionTable.Name) ~= "string" or string.len(actionTable.Name) == 0) then
return false, "Invalid action name" return false, "Invalid action name"
@ -716,7 +971,7 @@ function NazaraBuild:RegisterModule(moduleTable)
table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.inl") table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.inl")
table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.cpp") table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.cpp")
if (_OPTIONS["united"] and lowerCaseName ~= "core") then if (self.Config["UniteModules"] and lowerCaseName ~= "core") then
table.insert(moduleTable.FilesExcluded, "../src/Nazara/" .. moduleTable.Name .. "/Debug/NewOverload.cpp") table.insert(moduleTable.FilesExcluded, "../src/Nazara/" .. moduleTable.Name .. "/Debug/NewOverload.cpp")
end end
@ -735,7 +990,7 @@ function NazaraBuild:RegisterTool(toolTable)
return false, "This tool name is already in use" return false, "This tool name is already in use"
end end
if (toolTable.Directory == nil or type(toolTable.Directory) ~= "string" or string.len(toolTable.Directory) == 0) then if (toolTable.TargetDirectory == nil or type(toolTable.TargetDirectory) ~= "string" or string.len(toolTable.TargetDirectory) == 0) then
return false, "Invalid tool directory" return false, "Invalid tool directory"
end end
@ -744,7 +999,7 @@ function NazaraBuild:RegisterTool(toolTable)
end end
local lowerCaseKind = toolTable.Kind:lower() local lowerCaseKind = toolTable.Kind:lower()
if (lowerCaseKind == "library" or lowerCaseKind == "plugin" or lowerCaseKind == "consoleapp" or lowerCaseKind == "windowapp") then if (lowerCaseKind == "library" or lowerCaseKind == "plugin" or lowerCaseKind == "application") then
toolTable.Kind = lowerCaseKind toolTable.Kind = lowerCaseKind
else else
return false, "Invalid tool type" return false, "Invalid tool type"
@ -755,105 +1010,78 @@ function NazaraBuild:RegisterTool(toolTable)
return true return true
end end
local PosixOSes = { function NazaraBuild:Resolve(infoTable)
["bsd"] = true, if (infoTable.ClientOnly and self.Config["ServerMode"]) then
["linux"] = true, infoTable.Excluded = true
["macosx"] = true, infoTable.ExcludeReason = "excluded by command-line options (client-only)"
["solaris"] = true
}
function NazaraBuild:Process(infoTable)
local libraries = {}
for k, library in pairs(infoTable.Libraries) do
local moduleName = library:match("Nazara(%w+)")
local moduleTable = moduleName and self.Modules[moduleName:lower()]
local toolTable = moduleName and self.Tools[moduleName:lower()]
if (moduleTable) then
if (_OPTIONS["united"]) then
library = "NazaraEngine"
else
library = "Nazara" .. moduleTable.Name
end end
if (not _OPTIONS["united"] or infoTable.Type ~= "Module") then if (infoTable.Excludable) then
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") local optionName = "excludes-" .. string.lower(infoTable.Type .. "-" .. infoTable.Name)
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") newoption({
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") trigger = optionName,
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) description = "Excludes the " .. infoTable.Name .. " " .. string.lower(infoTable.Type) .. " and projects relying on it"
end })
else
local extLibTable = self.ExtLibs[library:lower()]
if (extLibTable) then
library = extLibTable.Name
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") if (_OPTIONS[optionName]) then
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") infoTable.Excluded = true
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d") infoTable.ExcludeReason = "excluded by command-line options"
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s")
else
if (toolTable and toolTable.Kind == "library") then
library = "Nazara" .. toolTable.Name
-- Import tools includes
for k,v in ipairs(toolTable.Includes) do
table.insert(infoTable.Includes, v)
end
table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s")
table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d")
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library)
else
table.insert(libraries, library)
end
end
end
end
infoTable.Libraries = libraries
for k,v in pairs(infoTable) do
local target = k:match("Os(%w+)")
if (target) then
local targetTable = infoTable[target]
if (targetTable) then
local excludeTargetTable = infoTable[target .. "Excluded"]
for platform, defineTable in pairs(v) do
platform = string.lower(platform)
if (platform == "posix") then
local osname = os.get()
if (PosixOSes[osname]) then
platform = osname
end end
end end
if (os.is(platform)) then if (type(infoTable.Libraries) == "function") then
for k,v in ipairs(defineTable) do infoTable.Libraries = infoTable.Libraries()
table.insert(targetTable, v)
end
elseif (excludeTargetTable) then
for k,v in ipairs(defineTable) do
table.insert(excludeTargetTable, v)
end
end
end
infoTable[k] = nil
end
end
end end
end end
function NazaraBuild:SetupInfoTable(infoTable) function NazaraBuild:SetupInfoTable(infoTable)
infoTable.BinaryPaths = {}
infoTable.BinaryPaths.x86 = {}
infoTable.BinaryPaths.x64 = {}
infoTable.ConfigurationLibraries = {} infoTable.ConfigurationLibraries = {}
infoTable.ConfigurationLibraries.DebugStatic = {} infoTable.ConfigurationLibraries.DebugStatic = {}
infoTable.ConfigurationLibraries.ReleaseStatic = {} infoTable.ConfigurationLibraries.ReleaseStatic = {}
infoTable.ConfigurationLibraries.DebugDynamic = {} infoTable.ConfigurationLibraries.DebugDynamic = {}
infoTable.ConfigurationLibraries.ReleaseDynamic = {} infoTable.ConfigurationLibraries.ReleaseDynamic = {}
infoTable.Excludable = true
infoTable.LibraryPaths = {}
infoTable.LibraryPaths.x86 = {}
infoTable.LibraryPaths.x64 = {}
local infos = {"Defines", "Files", "FilesExcluded", "Flags", "Includes", "Libraries"} local infos = {"Defines", "DynLib", "Files", "FilesExcluded", "Flags", "Includes", "Libraries"}
for k,v in ipairs(infos) do for k,v in ipairs(infos) do
infoTable[v] = {} infoTable[v] = {}
infoTable["Os" .. v] = {} infoTable["Os" .. v] = {}
end end
end end
function NazaraBuild:SetupExampleTable(infoTable)
self:SetupInfoTable(infoTable)
infoTable.Kind = "application"
infoTable.TargetDirectory = "../examples/bin"
end
function NazaraBuild:SetupExtlibTable(infoTable)
self:SetupInfoTable(infoTable)
infoTable.Kind = "library"
table.insert(infoTable.BinaryPaths.x86, "../extlibs/lib/common/x86")
table.insert(infoTable.BinaryPaths.x64, "../extlibs/lib/common/x64")
table.insert(infoTable.LibraryPaths.x86, "../extlibs/lib/common/x86")
table.insert(infoTable.LibraryPaths.x64, "../extlibs/lib/common/x64")
end
function NazaraBuild:SetupModuleTable(infoTable)
self:SetupInfoTable(infoTable)
infoTable.Kind = "library"
table.insert(infoTable.BinaryPaths.x86, "../extlibs/lib/common/x86")
table.insert(infoTable.BinaryPaths.x64, "../extlibs/lib/common/x64")
table.insert(infoTable.LibraryPaths.x86, "../extlibs/lib/common/x86")
table.insert(infoTable.LibraryPaths.x64, "../extlibs/lib/common/x64")
end
NazaraBuild.SetupToolTable = NazaraBuild.SetupInfoTable

View File

@ -1,14 +1,27 @@
MODULE.Name = "Audio" MODULE.Name = "Audio"
MODULE.ClientOnly = true
MODULE.Defines = { MODULE.Defines = {
"NAZARA_AUDIO_OPENAL" "NAZARA_AUDIO_OPENAL"
} }
MODULE.Libraries = { MODULE.Libraries = {
"NazaraCore", "NazaraCore"
}
MODULE.OsLibraries.Windows = {
"sndfile-1" "sndfile-1"
} }
MODULE.OsLibraries.Posix = {
"sndfile"
}
MODULE.OsDynLib.Windows = {
"soft_oal"
}
MODULE.OsFiles.Windows = { MODULE.OsFiles.Windows = {
"../src/Nazara/Audio/Win32/**.hpp", "../src/Nazara/Audio/Win32/**.hpp",
"../src/Nazara/Audio/Win32/**.cpp" "../src/Nazara/Audio/Win32/**.cpp"

View File

@ -1,6 +1,7 @@
MODULE.Name = "Core" MODULE.Name = "Core"
MODULE.Excludable = false -- Excluding the core makes no sense as everything relies on it
MODULE.Files = { -- Les autres fichiers seront ajoutés automatiquement MODULE.Files = { -- Other files will be automatically added
"../include/Nazara/Prerequesites.hpp", "../include/Nazara/Prerequesites.hpp",
"../include/Nazara/Math/**.hpp", "../include/Nazara/Math/**.hpp",
"../include/Nazara/Math/**.inl", "../include/Nazara/Math/**.inl",

View File

@ -2,5 +2,5 @@ MODULE.Name = "Physics"
MODULE.Libraries = { MODULE.Libraries = {
"NazaraCore", "NazaraCore",
"newton" "Newton"
} }

View File

@ -1,5 +1,7 @@
MODULE.Name = "Renderer" MODULE.Name = "Renderer"
MODULE.ClientOnly = true
MODULE.Defines = { MODULE.Defines = {
"NAZARA_RENDERER_OPENGL" "NAZARA_RENDERER_OPENGL"
} }

View File

@ -1,7 +1,6 @@
MODULE.Name = "Utility" MODULE.Name = "Utility"
MODULE.Libraries = { MODULE.Libraries = {
"freetype-s",
"NazaraCore", "NazaraCore",
"stb_image" "stb_image"
} }
@ -17,10 +16,12 @@ MODULE.OsFiles.Posix = {
} }
MODULE.OsLibraries.Windows = { MODULE.OsLibraries.Windows = {
"freetype-s",
"gdi32" "gdi32"
} }
MODULE.OsLibraries.Posix = { MODULE.OsLibraries.Posix = {
"freetype",
"X11", "X11",
"xcb", "xcb",
"xcb-cursor", "xcb-cursor",

View File

@ -0,0 +1,31 @@
MODULE.Name = "Vulkan"
MODULE.ClientOnly = true
MODULE.Defines = {
"VK_NO_PROTOTYPES"
}
MODULE.Libraries = {
"NazaraCore",
"NazaraUtility"
}
MODULE.OsDefines.Linux = {
-- "VK_USE_PLATFORM_MIR_KHR",
"VK_USE_PLATFORM_XCB_KHR"
-- "VK_USE_PLATFORM_XLIB_KHR",
-- "VK_USE_PLATFORM_WAYLAND_KHR"
}
MODULE.OsDefines.BSD = MODULE.OsDefines.Linux
MODULE.OsDefines.Solaris = MODULE.OsDefines.Linux
MODULE.OsDefines.Windows = {
"VK_USE_PLATFORM_WIN32_KHR"
}
MODULE.OsFiles.Windows = {
"../src/Nazara/Vulkan/Win32/**.hpp",
"../src/Nazara/Vulkan/Win32/**.cpp"
}

View File

@ -1,11 +1,11 @@
TOOL.Name = "Assimp" TOOL.Name = "Assimp"
TOOL.Directory = "../SDK/lib" TOOL.Directory = "../plugins/Assimp"
TOOL.Kind = "Plugin" TOOL.Kind = "Plugin"
TOOL.TargetDirectory = "../SDK/lib"
TOOL.CopyTargetToExampleDir = true
TOOL.Includes = { TOOL.Includes = {
"../extlibs/include",
"../include", "../include",
"../plugins/Assimp" "../plugins/Assimp"
} }

View File

@ -1,7 +1,8 @@
TOOL.Name = "SDK" TOOL.Name = "SDK"
TOOL.Directory = "../SDK/lib" TOOL.Directory = "../SDK"
TOOL.Kind = "Library" TOOL.Kind = "Library"
TOOL.TargetDirectory = "../SDK/lib"
TOOL.Defines = { TOOL.Defines = {
"NDK_BUILD" "NDK_BUILD"
@ -20,14 +21,11 @@ TOOL.Files = {
"../SDK/src/NDK/**.cpp" "../SDK/src/NDK/**.cpp"
} }
TOOL.Libraries = { TOOL.Libraries = function()
"NazaraCore", local libraries = {}
"NazaraAudio", for k,v in pairs(NazaraBuild.Modules) do
"NazaraLua", table.insert(libraries, "Nazara" .. v.Name)
"NazaraNetwork", end
"NazaraNoise",
"NazaraPhysics", return libraries
"NazaraUtility", end
"NazaraRenderer",
"NazaraGraphics"
}

View File

@ -1,7 +1,8 @@
TOOL.Name = "SDKServer" TOOL.Name = "SDKServer"
TOOL.Directory = "../SDK/lib" TOOL.Directory = "../SDK"
TOOL.Kind = "Library" TOOL.Kind = "Library"
TOOL.TargetDirectory = "../SDK/lib"
TOOL.Defines = { TOOL.Defines = {
"NDK_BUILD", "NDK_BUILD",
@ -21,7 +22,7 @@ TOOL.Files = {
"../SDK/src/NDK/**.cpp" "../SDK/src/NDK/**.cpp"
} }
-- Exlude client-only files -- Excludes client-only files
TOOL.FilesExcluded = { TOOL.FilesExcluded = {
"../SDK/**/CameraComponent.*", "../SDK/**/CameraComponent.*",
"../SDK/**/Console.*", "../SDK/**/Console.*",
@ -35,6 +36,7 @@ TOOL.FilesExcluded = {
"../SDK/**/LuaBinding_Renderer.*" "../SDK/**/LuaBinding_Renderer.*"
} }
TOOL.Libraries = { TOOL.Libraries = {
"NazaraCore", "NazaraCore",
"NazaraLua", "NazaraLua",

View File

@ -1,7 +1,9 @@
TOOL.Name = "UnitTests" TOOL.Name = "UnitTests"
TOOL.Directory = "../tests" TOOL.Directory = "../tests"
TOOL.Kind = "ConsoleApp" TOOL.EnableConsole = true
TOOL.Kind = "Application"
TOOL.TargetDirectory = TOOL.Directory
TOOL.Defines = { TOOL.Defines = {
} }
@ -19,9 +21,10 @@ TOOL.Libraries = {
"NazaraCore", "NazaraCore",
"NazaraAudio", "NazaraAudio",
"NazaraLua", "NazaraLua",
"NazaraGraphics",
"NazaraRenderer",
"NazaraNetwork",
"NazaraNoise", "NazaraNoise",
"NazaraPhysics", "NazaraPhysics",
"NazaraUtility", "NazaraUtility"
"NazaraRenderer",
"NazaraGraphics"
} }

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "DopplerEffect" EXAMPLE.Name = "DopplerEffect"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -1,15 +1,11 @@
EXAMPLE.Name = "FirstScene" EXAMPLE.Name = "FirstScene"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"
} }
EXAMPLE.Libraries = { EXAMPLE.Libraries = {
"NazaraCore",
"NazaraGraphics",
"NazaraRenderer",
"NazaraUtility",
"NazaraSDK" "NazaraSDK"
} }

View File

@ -1,25 +1,27 @@
/* /*
** FirstScene - Première scène graphique * FirstScene - Première scène graphique
** Prérequis: Aucun * Prérequis: Aucun
** Utilisation du module utilitaire et graphique * Utilisation du module utilitaire et graphique
** Présente: ** Présente :
** - Création et gestion d'une fenêtre (Traitement des évènements clavier/souris) * -Création et gestion d'une fenêtre (Traitement des évènements clavier/souris)
** - Gestion du clavier (Récupération de l'état d'une touche) * -Gestion du clavier(Récupération de l'état d'une touche)
** - Des outils pour afficher une scène basique via le chargement d'un modèle (et son affichage) * -Des outils pour afficher une scène basique via le chargement d'un modèle (et son affichage)
** - Éclairage directionnel * -Éclairage directionnel
** - Gestion d'une caméra free-fly (Avec déplacement fluide) * -Gestion d'une caméra free-fly (Avec déplacement fluide)
** - Gestion basique d'une horloge * -Gestion basique d'une horloge
* -Console
*/ */
#include <Nazara/Core/Clock.hpp> // Horloges #include <Nazara/Core/Clock.hpp> // Horloges
#include <Nazara/Lua.hpp> // Module de scripting
#include <Nazara/Graphics.hpp> // Module graphique #include <Nazara/Graphics.hpp> // Module graphique
#include <Nazara/Renderer.hpp> // Module de rendu #include <Nazara/Renderer.hpp> // Module de rendu
#include <Nazara/Utility.hpp> // Module utilitaire #include <Nazara/Utility.hpp> // Module utilitaire
#include <NDK/Components/CameraComponent.hpp> #include <NDK/Application.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components.hpp>
#include <NDK/Components/LightComponent.hpp> #include <NDK/Console.hpp>
#include <NDK/Components/NodeComponent.hpp> #include <NDK/Systems.hpp>
#include <NDK/Systems/RenderSystem.hpp> #include <NDK/LuaAPI.hpp>
#include <NDK/Sdk.hpp> #include <NDK/Sdk.hpp>
#include <NDK/World.hpp> #include <NDK/World.hpp>
#include <iostream> #include <iostream>
@ -29,26 +31,15 @@ Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& ta
int main() int main()
{ {
// Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, // Ndk::Application est une classe s'occupant de l'initialisation du moteur ainsi que de la gestion de beaucoup de choses
// les composants, systèmes, etc. Ndk::Application application;
// NzInitializer est une classe RAII appelant Initialize dans son constructeur et Uninitialize dans son destructeur.
// Autrement dit, une fois ceci fait nous n'avons plus à nous soucier de la libération du moteur.
Nz::Initializer<Ndk::Sdk> nazara;
if (!nazara)
{
// Une erreur s'est produite dans l'initialisation d'un des modules
std::cout << "Failed to initialize Nazara, see NazaraLog.log for further informations" << std::endl;
std::getchar(); // On laise le temps de voir l'erreur
return EXIT_FAILURE;
}
// Nazara étant initialisé, nous pouvons créer le monde pour contenir notre scène. // Nazara étant initialisé, nous pouvons créer le monde pour contenir notre scène.
// Dans un ECS, le monde représente bien ce que son nom indique, c'est l'ensemble de ce qui existe au niveau de l'application. // Dans un ECS, le monde représente bien ce que son nom indique, c'est l'ensemble de ce qui existe au niveau de l'application.
// Il contient les systèmes et les entités, ces dernières contiennent les composants. // Il contient les systèmes et les entités, ces dernières contiennent les composants.
// Il est possible d'utiliser plusieurs mondes au sein d'une même application, par exemple pour gérer un mélange de 2D et de 3D, // Il est possible d'utiliser plusieurs mondes au sein d'une même application, par exemple pour gérer un mélange de 2D et de 3D,
// mais nous verrons cela dans un prochain exemple. // mais nous verrons cela dans un prochain exemple.
Ndk::World world; Ndk::WorldHandle world = application.AddWorld().CreateHandle();
// Nous pouvons maintenant ajouter des systèmes, mais dans cet exemple nous nous contenterons de ceux de base. // Nous pouvons maintenant ajouter des systèmes, mais dans cet exemple nous nous contenterons de ceux de base.
@ -73,7 +64,7 @@ int main()
Nz::SkyboxBackgroundRef skybox = Nz::SkyboxBackground::New(std::move(texture)); Nz::SkyboxBackgroundRef skybox = Nz::SkyboxBackground::New(std::move(texture));
// Accédons maintenant au système de rendu faisant partie du monde // Accédons maintenant au système de rendu faisant partie du monde
Ndk::RenderSystem& renderSystem = world.GetSystem<Ndk::RenderSystem>(); // Une assertion valide la précondition "le système doit faire partie du monde" Ndk::RenderSystem& renderSystem = world->GetSystem<Ndk::RenderSystem>(); // Une assertion valide la précondition "le système doit faire partie du monde"
// Nous assignons ensuite notre skybox comme "fond par défaut" du système // Nous assignons ensuite notre skybox comme "fond par défaut" du système
// La notion "par défaut" existe parce qu'une caméra pourrait utiliser son propre fond lors du rendu, // La notion "par défaut" existe parce qu'une caméra pourrait utiliser son propre fond lors du rendu,
@ -101,7 +92,7 @@ int main()
// Le format OBJ ne précise aucune échelle pour ses données, contrairement à Nazara (une unité = un mètre en 3D). // Le format OBJ ne précise aucune échelle pour ses données, contrairement à Nazara (une unité = un mètre en 3D).
// Comme le vaisseau est très grand (Des centaines de mètres de long), nous allons le rendre plus petit pour les besoins de la démo. // Comme le vaisseau est très grand (Des centaines de mètres de long), nous allons le rendre plus petit pour les besoins de la démo.
// Ce paramètre sert à indiquer la mise à l'échelle désirée lors du chargement du modèle. // Ce paramètre sert à indiquer la mise à l'échelle désirée lors du chargement du modèle.
params.mesh.scale.Set(0.01f); // Un centième de la taille originelle params.mesh.matrix.MakeScale(Nz::Vector3f(0.01f)); // Un centième de la taille originelle
// Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend (haut-gauche) // Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend (haut-gauche)
// Nous devons donc indiquer au moteur de les retourner lors du chargement // Nous devons donc indiquer au moteur de les retourner lors du chargement
@ -146,7 +137,7 @@ int main()
// Bien, nous avons un modèle valide, mais celui-ci ne consiste qu'en des informations de rendu, de matériaux et de textures. // Bien, nous avons un modèle valide, mais celui-ci ne consiste qu'en des informations de rendu, de matériaux et de textures.
// Commençons donc par créer une entité vide, cela se fait en demandant au monde de générer une nouvelle entité. // Commençons donc par créer une entité vide, cela se fait en demandant au monde de générer une nouvelle entité.
Ndk::EntityHandle spaceship = world.CreateEntity(); Ndk::EntityHandle spaceship = world->CreateEntity();
// Note: Nous ne récupérons pas l'entité directement mais un "handle" vers elle, ce dernier est un pointeur intelligent non-propriétaire. // Note: Nous ne récupérons pas l'entité directement mais un "handle" vers elle, ce dernier est un pointeur intelligent non-propriétaire.
// Pour des raisons techniques, le pointeur de l'entité peut venir à changer, ou l'entité être simplement détruite pour n'importe quelle raison. // Pour des raisons techniques, le pointeur de l'entité peut venir à changer, ou l'entité être simplement détruite pour n'importe quelle raison.
@ -159,6 +150,7 @@ int main()
// Étant donné que par défaut, un NodeComponent se place en (0,0,0) sans rotation et avec une échelle de 1,1,1 et que cela nous convient, // Étant donné que par défaut, un NodeComponent se place en (0,0,0) sans rotation et avec une échelle de 1,1,1 et que cela nous convient,
// nous n'avons pas besoin d'agir sur le composant créé. // nous n'avons pas besoin d'agir sur le composant créé.
spaceship->AddComponent<Ndk::NodeComponent>(); spaceship->AddComponent<Ndk::NodeComponent>();
//spaceship->AddComponent<Ndk::VelocityComponent>().linearVelocity.Set(-1.f, 0.f, 0.f);
// Bien, notre entité nouvellement créé dispose maintenant d'une position dans la scène, mais est toujours invisible // Bien, notre entité nouvellement créé dispose maintenant d'une position dans la scène, mais est toujours invisible
// Nous lui ajoutons donc un GraphicsComponent // Nous lui ajoutons donc un GraphicsComponent
@ -178,7 +170,7 @@ int main()
// Nous créons donc une seconde entité // Nous créons donc une seconde entité
// Note: La création d'entité est une opération légère au sein du moteur, mais plus vous aurez d'entités et plus le processeur devra travailler. // Note: La création d'entité est une opération légère au sein du moteur, mais plus vous aurez d'entités et plus le processeur devra travailler.
Ndk::EntityHandle camera = world.CreateEntity(); Ndk::EntityHandle camera = world->CreateEntity();
// Notre caméra a elle aussi besoin d'être positionnée dans la scène // Notre caméra a elle aussi besoin d'être positionnée dans la scène
Ndk::NodeComponent& cameraNode = camera->AddComponent<Ndk::NodeComponent>(); Ndk::NodeComponent& cameraNode = camera->AddComponent<Ndk::NodeComponent>();
@ -188,6 +180,9 @@ int main()
// Et dispose d'un composant pour chaque point de vue de la scène, le CameraComponent // Et dispose d'un composant pour chaque point de vue de la scène, le CameraComponent
Ndk::CameraComponent& cameraComp = camera->AddComponent<Ndk::CameraComponent>(); Ndk::CameraComponent& cameraComp = camera->AddComponent<Ndk::CameraComponent>();
// Ajoutons un composant écouteur, si nous venions à avoir du son
camera->AddComponent<Ndk::ListenerComponent>();
// Et on n'oublie pas de définir les plans délimitant le champs de vision // Et on n'oublie pas de définir les plans délimitant le champs de vision
// (Seul ce qui se trouvera entre les deux plans sera rendu) // (Seul ce qui se trouvera entre les deux plans sera rendu)
@ -208,7 +203,7 @@ int main()
// Nous allons créer une lumière directionnelle pour représenter la nébuleuse de notre skybox // Nous allons créer une lumière directionnelle pour représenter la nébuleuse de notre skybox
// Encore une fois, nous créons notre entité // Encore une fois, nous créons notre entité
Ndk::EntityHandle nebulaLight = world.CreateEntity(); Ndk::EntityHandle nebulaLight = world->CreateEntity();
// Lui ajoutons une position dans la scène // Lui ajoutons une position dans la scène
Ndk::NodeComponent& nebulaLightNode = nebulaLight->AddComponent<Ndk::NodeComponent>(); Ndk::NodeComponent& nebulaLightNode = nebulaLight->AddComponent<Ndk::NodeComponent>();
@ -246,7 +241,7 @@ int main()
Nz::RenderTargetParameters parameters; Nz::RenderTargetParameters parameters;
parameters.antialiasingLevel = 4; parameters.antialiasingLevel = 4;
Nz::RenderWindow window(mode, windowTitle, style, parameters); Nz::RenderWindow& window = application.AddWindow<Nz::RenderWindow>(mode, windowTitle, style, parameters);
if (!window.IsValid()) if (!window.IsValid())
{ {
std::cout << "Failed to create render window" << std::endl; std::cout << "Failed to create render window" << std::endl;
@ -272,8 +267,70 @@ int main()
bool smoothMovement = true; bool smoothMovement = true;
Nz::Vector3f targetPos = cameraNode.GetPosition(); Nz::Vector3f targetPos = cameraNode.GetPosition();
// Début de la boucle de rendu du programme // Pour ajouter une console à notre application, nous avons besoin d'un monde 2D pour gérer ces rendus
while (window.IsOpen()) Ndk::WorldHandle world2D = application.AddWorld().CreateHandle();
world2D->GetSystem<Ndk::RenderSystem>().SetDefaultBackground(nullptr);
world2D->GetSystem<Ndk::RenderSystem>().SetGlobalUp(Nz::Vector3f::Down());
// Nous ajoutons une caméra comme précédement
Ndk::EntityHandle viewEntity = world2D->CreateEntity();
viewEntity->AddComponent<Ndk::NodeComponent>();
// À la différence que celui-ci effectuera une projection orthogonale
Ndk::CameraComponent& viewer = viewEntity->AddComponent<Ndk::CameraComponent>();
viewer.SetTarget(&window);
viewer.SetProjectionType(Nz::ProjectionType_Orthogonal);
// Nous créons un environnement Lua pour gérer nos scripts
Nz::LuaInstance lua;
// Faisons en sorte d'enregistrer les classes du moteur dans cet environnement
Ndk::LuaAPI::RegisterClasses(lua);
// Ensuite nous créons la console en elle-même
Ndk::Console console(*world2D, Nz::Vector2f(window.GetWidth(), window.GetHeight() / 4), lua);
// Nous redirigeons les logs vers cette console
Nz::Log::OnLogWriteType::ConnectionGuard logGuard = Nz::Log::OnLogWrite.Connect([&console] (const Nz::String& str)
{
console.AddLine(str);
});
// Nous réécrivons la fonction "print" du Lua pour la rediriger vers la console
lua.PushFunction([&console] (Nz::LuaInstance& instance)
{
Nz::StringStream stream;
unsigned int argCount = instance.GetStackTop();
instance.GetGlobal("tostring");
for (unsigned int i = 1; i <= argCount; ++i)
{
instance.PushValue(-1); // ToString
instance.PushValue(i); // Arg
instance.Call(1, 1);
std::size_t length;
const char* str = instance.CheckString(-1, &length);
if (i > 1)
stream << '\t';
stream << Nz::String(str, length);
instance.Pop(1);
}
console.AddLine(stream);
return 0;
});
lua.SetGlobal("print");
// Définissons quelques variables de base
lua.PushGlobal("Application", Ndk::Application::Instance());
lua.PushGlobal("Console", console.CreateHandle());
lua.PushGlobal("Spaceship", spaceship->CreateHandle());
lua.PushGlobal("World", world->CreateHandle());
// Début de la boucle de rendu du programme (s'occupant par exemple de mettre à jour le monde)
while (application.Run())
{ {
// Ensuite nous allons traiter les évènements (Étape indispensable pour la fenêtre) // Ensuite nous allons traiter les évènements (Étape indispensable pour la fenêtre)
Nz::WindowEvent event; Nz::WindowEvent event;
@ -283,6 +340,9 @@ int main()
{ {
case Nz::WindowEventType_MouseMoved: // La souris a bougé case Nz::WindowEventType_MouseMoved: // La souris a bougé
{ {
if (console.IsVisible())
break;
// Gestion de la caméra free-fly (Rotation) // Gestion de la caméra free-fly (Rotation)
float sensitivity = 0.3f; // Sensibilité de la souris float sensitivity = 0.3f; // Sensibilité de la souris
@ -297,15 +357,18 @@ int main()
// Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenêtre // Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenêtre
// Cette fonction est codée de sorte à ne pas provoquer d'évènement MouseMoved // Cette fonction est codée de sorte à ne pas provoquer d'évènement MouseMoved
Nz::Mouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window); Nz::Mouse::SetPosition(window.GetWidth() / 2, window.GetHeight() / 2, window);
break; break;
} }
case Nz::WindowEventType_Quit: // L'utilisateur a cliqué sur la croix, ou l'OS veut terminer notre programme case Nz::WindowEventType_Quit: // L'utilisateur a cliqué sur la croix, ou l'OS veut terminer notre programme
window.Close(); // On demande la fermeture de la fenêtre (Qui aura lieu au prochain tour de boucle) application.Quit();
break; break;
case Nz::WindowEventType_KeyPressed: // Une touche a été pressée ! case Nz::WindowEventType_KeyPressed: // Une touche a été pressée !
if (console.IsVisible())
console.SendEvent(event);
if (event.key.code == Nz::Keyboard::Key::Escape) if (event.key.code == Nz::Keyboard::Key::Escape)
window.Close(); window.Close();
else if (event.key.code == Nz::Keyboard::F1) else if (event.key.code == Nz::Keyboard::F1)
@ -318,6 +381,19 @@ int main()
else else
smoothMovement = true; smoothMovement = true;
} }
else if (event.key.code == Nz::Keyboard::F9)
console.Show(!console.IsVisible());
break;
case Nz::WindowEventType_TextEntered:
{
if (console.IsVisible())
console.SendCharacter(event.text.character);
break;
}
case Nz::WindowEventType_Resized:
console.SetSize({float(event.size.width), event.size.height / 4.f});
break; break;
default: default:
@ -337,11 +413,12 @@ int main()
{ {
// Le temps écoulé en seconde depuis la dernière fois que ce bloc a été exécuté // Le temps écoulé en seconde depuis la dernière fois que ce bloc a été exécuté
float elapsedTime = updateAccumulator / 1000000.f; float elapsedTime = updateAccumulator / 1000000.f;
std::cout << elapsedTime << std::endl;
// Vitesse de déplacement de la caméra // Vitesse de déplacement de la caméra
float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde
if (!console.IsVisible())
{
// Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux // Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space)) if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space))
cameraSpeed *= 2.f; cameraSpeed *= 2.f;
@ -372,16 +449,11 @@ int main()
// Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc... // Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl)) if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl))
targetPos += Nz::Vector3f::Down() * cameraSpeed; targetPos += Nz::Vector3f::Down() * cameraSpeed;
cameraNode.SetPosition((smoothMovement) ? DampedString(cameraNode.GetPosition(), targetPos, elapsedTime) : targetPos, Nz::CoordSys_Global);
updateAccumulator = 0;
} }
// Et maintenant pour rendre la scène, il nous suffit de mettre à jour le monde en lui envoyant le temps depuis la dernière mise à jour cameraNode.SetPosition((smoothMovement) ? DampedString(cameraNode.GetPosition(), targetPos, elapsedTime) : targetPos, Nz::CoordSys_Global);
// Note: La plupart des systèmes, à l'exception de celui de rendu, ont une fréquence de mise à jour fixe (modifiable) updateAccumulator = 0;
// Il n'est donc pas nécessaire de limiter vous-même les mises à jour du monde }
world.Update(elapsedUS / 1000000.f);
// Après avoir dessiné sur la fenêtre, il faut s'assurer qu'elle affiche cela // Après avoir dessiné sur la fenêtre, il faut s'assurer qu'elle affiche cela
// Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering) // Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering)
@ -430,7 +502,7 @@ Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& ta
if (Nz::NumberEquals(displacementLength, 0.f)) if (Nz::NumberEquals(displacementLength, 0.f))
return currentPos; return currentPos;
float invDisplacementLength = 1.f/displacementLength; float invDisplacementLength = 1.f / displacementLength;
const float dampConstant = 0.000065f; // Something v.small to offset 1/ displacement length const float dampConstant = 0.000065f; // Something v.small to offset 1/ displacement length

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "HardwareInfo" EXAMPLE.Name = "HardwareInfo"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Defines = { EXAMPLE.Defines = {
"NAZARA_RENDERER_OPENGL" "NAZARA_RENDERER_OPENGL"

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "MeshInfos" EXAMPLE.Name = "MeshInfos"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -173,12 +173,7 @@ int main()
Nz::String data; Nz::String data;
if (!matData.GetStringParameter(Nz::MaterialData::FilePath, &data)) if (!matData.GetStringParameter(Nz::MaterialData::FilePath, &data))
{
if (matData.HasParameter(Nz::MaterialData::CustomDefined))
data = "<Custom>"; data = "<Custom>";
else
data = "<No data>";
}
std::cout << "\t" << (i+1) << ": " << data << std::endl; std::cout << "\t" << (i+1) << ": " << data << std::endl;
} }

20
examples/Tut00/build.lua Normal file
View File

@ -0,0 +1,20 @@
EXAMPLE.Name = "Tut00_EmptyProject"
EXAMPLE.EnableConsole = true
EXAMPLE.Files = {
"main.cpp"
}
EXAMPLE.Libraries = {
"NazaraAudio",
"NazaraCore",
"NazaraGraphics",
"NazaraLua",
"NazaraNetwork",
"NazaraNoise",
"NazaraPhysics",
"NazaraRenderer",
"NazaraUtility",
"NazaraSDK"
}

24
examples/Tut00/main.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <Nazara/Audio.hpp>
#include <Nazara/Core.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Lua.hpp>
#include <Nazara/Network.hpp>
#include <Nazara/Noise.hpp>
#include <Nazara/Physics.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
#include <NDK/Application.hpp>
#include <iostream>
#include <vector>
#include <unordered_map>
int main()
{
// This "example" has only one purpose: Giving an empty project for you to test whatever you want
// If you wish to have multiple test projects, you only have to copy/paste this directory and change the name in the build.lua
Ndk::Application app;
// Do what you want here
return EXIT_SUCCESS;
}

View File

@ -1,15 +1,11 @@
EXAMPLE.Name = "Tut01_HelloWorld" EXAMPLE.Name = "Tut01_HelloWorld"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"
} }
EXAMPLE.Libraries = { EXAMPLE.Libraries = {
"NazaraCore",
"NazaraGraphics",
"NazaraRenderer",
"NazaraUtility",
"NazaraSDK" "NazaraSDK"
} }

View File

@ -7,11 +7,21 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \brief Mixes channels in mono
*
* \param input Input buffer with multiples channels
* \param output Output butter for mono
* \param channelCount Number of channels
* \param frameCount Number of frames
*
* \remark The input buffer may be the same as the output one
*/
template<typename T> template<typename T>
void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount) void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
{ {
///DOC: Le buffer d'entrée peut être le même que le buffer de sortie // To avoid overflow, we use, as an accumulator, a type which is large enough: (u)int 64 bits for integers, double for floatings
// Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants
typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt; typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt;
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest; typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;
@ -19,7 +29,7 @@ namespace Nz
{ {
Biggest acc = Biggest(0); Biggest acc = Biggest(0);
for (unsigned int j = 0; j < channelCount; ++j) for (unsigned int j = 0; j < channelCount; ++j)
acc += input[i*channelCount + j]; acc += input[i * channelCount + j];
output[i] = static_cast<T>(acc / channelCount); output[i] = static_cast<T>(acc / channelCount);
} }

View File

@ -27,18 +27,23 @@
#ifndef NAZARA_CONFIG_AUDIO_HPP #ifndef NAZARA_CONFIG_AUDIO_HPP
#define NAZARA_CONFIG_AUDIO_HPP #define NAZARA_CONFIG_AUDIO_HPP
/// Modifier la configuration d'un module nécessite une recompilation quasi-intégrale de celui-ci et de ceux en héritant /*!
* \defgroup audio (NazaraAudio) Audio module
* Audio/System module including classes to handle music, sound, etc...
*/
// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) /// Each modification of a parameter needs a recompilation of the module
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_AUDIO_MANAGE_MEMORY 0 #define NAZARA_AUDIO_MANAGE_MEMORY 0
// Active les tests de sécurité supplémentaires (Teste notamment les arguments des fonctions, conseillé pour le développement) // Activate the security tests based on the code (Advised for development)
#define NAZARA_AUDIO_SAFE 1 #define NAZARA_AUDIO_SAFE 1
// Le nombre de buffers utilisés lors du streaming d'objets audio (Au moins deux) // The number of buffers used for audio streaming (At least two)
#define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2 #define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2
/// Vérification des valeurs et types de certaines constantes /// Checking the values and types of certain constants
#include <Nazara/Audio/ConfigCheck.hpp> #include <Nazara/Audio/ConfigCheck.hpp>
#if !defined(NAZARA_STATIC) #if !defined(NAZARA_STATIC)

View File

@ -7,12 +7,12 @@
#ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP #ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP
#define NAZARA_CONFIG_CHECK_AUDIO_HPP #define NAZARA_CONFIG_CHECK_AUDIO_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp /// This file is used to check the constant values defined in Config.hpp
#include <type_traits> #include <type_traits>
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err) #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug // We force the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY
#undef NAZARA_AUDIO_MANAGE_MEMORY #undef NAZARA_AUDIO_MANAGE_MEMORY
#define NAZARA_AUDIO_MANAGE_MEMORY 0 #define NAZARA_AUDIO_MANAGE_MEMORY 0

View File

@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Audio module" // This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp // We assume that Debug.hpp has already been included, same thing for Config.hpp
#if NAZARA_AUDIO_MANAGE_MEMORY #if NAZARA_AUDIO_MANAGE_MEMORY
#undef delete #undef delete
#undef new #undef new

View File

@ -13,7 +13,7 @@ namespace Nz
{ {
AudioFormat_Unknown = -1, AudioFormat_Unknown = -1,
// La valeur entière est le nombre de canaux possédés par ce format // The integer value is the number of channels used by the format
AudioFormat_Mono = 1, AudioFormat_Mono = 1,
AudioFormat_Stereo = 2, AudioFormat_Stereo = 2,
AudioFormat_Quad = 4, AudioFormat_Quad = 4,

View File

@ -15,18 +15,18 @@
#include <Nazara/Core/String.hpp> #include <Nazara/Core/String.hpp>
#include <vector> #include <vector>
// Inclusion des headers OpenAL // Inclusion of OpenAL headers
// Étant donné que les headers OpenAL ne nous permettent pas de n'avoir que les signatures sans les pointeurs de fonctions // OpenAL headers does not allow us to only get the signatures without the pointers to the functions
// Et que je ne souhaite pas les modifier, je suis contraint de les placer dans un espace de nom différent pour ensuite // And I do no want to modify them, I'm obliged to put them in a different namespace
// remettre dans l'espace global les choses intéressantes (les typedef notamment) // to put only interesting things back in the global namespace (specially typedef)
namespace OpenALDetail namespace OpenALDetail
{ {
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
} }
// Si quelqu'un a une meilleure idée ... // If someone has a better idea ...
using OpenALDetail::ALboolean; using OpenALDetail::ALboolean;
using OpenALDetail::ALbyte; using OpenALDetail::ALbyte;
using OpenALDetail::ALchar; using OpenALDetail::ALchar;

View File

@ -7,6 +7,13 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Creates a new sound buffer from the arguments
* \return A reference to the newly created sound buffer
*
* \param args Arguments for the sound buffer
*/
template<typename... Args> template<typename... Args>
SoundBufferRef SoundBuffer::New(Args&&... args) SoundBufferRef SoundBuffer::New(Args&&... args)
{ {

View File

@ -12,7 +12,7 @@
#include <Nazara/Audio/Enums.hpp> #include <Nazara/Audio/Enums.hpp>
#include <Nazara/Math/Vector3.hpp> #include <Nazara/Math/Vector3.hpp>
///TODO: Faire hériter SoundEmitter de Node ///TODO: Inherit SoundEmitter from Node
namespace Nz namespace Nz
{ {

View File

@ -26,6 +26,7 @@ namespace Nz
template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept; template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept;
template<typename T> std::size_t CountOf(const T& c); template<typename T> std::size_t CountOf(const T& c);
template<typename T> void HashCombine(std::size_t& seed, const T& v); template<typename T> void HashCombine(std::size_t& seed, const T& v);
template<typename T> T ReverseBits(T integer);
template<typename T> template<typename T>
struct PointedType struct PointedType

View File

@ -28,6 +28,8 @@ namespace Nz
{ {
return (object .* std::forward<F>(fn))(std::get<S>(std::forward<Tuple>(t))...); return (object .* std::forward<F>(fn))(std::get<S>(std::forward<Tuple>(t))...);
} }
NAZARA_CORE_API extern const UInt8 BitReverseTable256[256];
} }
/*! /*!
@ -122,6 +124,7 @@ namespace Nz
template<typename T, std::size_t N> template<typename T, std::size_t N>
constexpr std::size_t CountOf(T(&name)[N]) noexcept constexpr std::size_t CountOf(T(&name)[N]) noexcept
{ {
NazaraUnused(name);
return N; return N;
} }
@ -164,6 +167,23 @@ namespace Nz
seed = static_cast<std::size_t>(b * kMul); seed = static_cast<std::size_t>(b * kMul);
} }
/*!
* \ingroup core
* \brief Reverse the bit order of the integer
* \return integer with reversed bits
*
* \param integer Integer whose bits are to be reversed
*/
template<typename T>
T ReverseBits(T integer)
{
T reversed = 0;
for (std::size_t i = 0; i < sizeof(T); ++i)
reversed |= T(Detail::BitReverseTable256[(integer >> i * 8) & 0xFF]) << (sizeof(T) * 8 - (i + 1) * 8);
return reversed;
}
template<typename T> struct PointedType<T*> {typedef T type;}; template<typename T> struct PointedType<T*> {typedef T type;};
template<typename T> struct PointedType<T* const> {typedef T type;}; template<typename T> struct PointedType<T* const> {typedef T type;};
template<typename T> struct PointedType<T* volatile> {typedef T type;}; template<typename T> struct PointedType<T* volatile> {typedef T type;};

View File

@ -26,9 +26,9 @@ namespace Nz
class Bit; class Bit;
Bitset(); Bitset();
explicit Bitset(unsigned int bitCount, bool val); explicit Bitset(std::size_t bitCount, bool val);
explicit Bitset(const char* bits); explicit Bitset(const char* bits);
Bitset(const char* bits, unsigned int bitCount); Bitset(const char* bits, std::size_t bitCount);
Bitset(const Bitset& bitset) = default; Bitset(const Bitset& bitset) = default;
explicit Bitset(const String& bits); explicit Bitset(const String& bits);
template<typename T> Bitset(T value); template<typename T> Bitset(T value);
@ -36,16 +36,16 @@ namespace Nz
~Bitset() noexcept = default; ~Bitset() noexcept = default;
void Clear() noexcept; void Clear() noexcept;
unsigned int Count() const; std::size_t Count() const;
void Flip(); void Flip();
unsigned int FindFirst() const; std::size_t FindFirst() const;
unsigned int FindNext(unsigned int bit) const; std::size_t FindNext(std::size_t bit) const;
Block GetBlock(unsigned int i) const; Block GetBlock(std::size_t i) const;
unsigned int GetBlockCount() const; std::size_t GetBlockCount() const;
unsigned int GetCapacity() const; std::size_t GetCapacity() const;
unsigned int GetSize() const; std::size_t GetSize() const;
void PerformsAND(const Bitset& a, const Bitset& b); void PerformsAND(const Bitset& a, const Bitset& b);
void PerformsNOT(const Bitset& a); void PerformsNOT(const Bitset& a);
@ -54,19 +54,19 @@ namespace Nz
bool Intersects(const Bitset& bitset) const; bool Intersects(const Bitset& bitset) const;
void Reserve(unsigned int bitCount); void Reserve(std::size_t bitCount);
void Resize(unsigned int bitCount, bool defaultVal = false); void Resize(std::size_t bitCount, bool defaultVal = false);
void Reset(); void Reset();
void Reset(unsigned int bit); void Reset(std::size_t bit);
void Set(bool val = true); void Set(bool val = true);
void Set(unsigned int bit, bool val = true); void Set(std::size_t bit, bool val = true);
void SetBlock(unsigned int i, Block block); void SetBlock(std::size_t i, Block block);
void Swap(Bitset& bitset); void Swap(Bitset& bitset);
bool Test(unsigned int bit) const; bool Test(std::size_t bit) const;
bool TestAll() const; bool TestAll() const;
bool TestAny() const; bool TestAny() const;
bool TestNone() const; bool TestNone() const;
@ -74,9 +74,9 @@ namespace Nz
template<typename T> T To() const; template<typename T> T To() const;
String ToString() const; String ToString() const;
void UnboundedReset(unsigned int bit); void UnboundedReset(std::size_t bit);
void UnboundedSet(unsigned int bit, bool val = true); void UnboundedSet(std::size_t bit, bool val = true);
bool UnboundedTest(unsigned int bit) const; bool UnboundedTest(std::size_t bit) const;
Bit operator[](int index); Bit operator[](int index);
bool operator[](int index) const; bool operator[](int index) const;
@ -93,20 +93,20 @@ namespace Nz
Bitset& operator^=(const Bitset& bitset); Bitset& operator^=(const Bitset& bitset);
static constexpr Block fullBitMask = std::numeric_limits<Block>::max(); static constexpr Block fullBitMask = std::numeric_limits<Block>::max();
static constexpr unsigned int bitsPerBlock = std::numeric_limits<Block>::digits; static constexpr std::size_t bitsPerBlock = std::numeric_limits<Block>::digits;
static constexpr unsigned int npos = std::numeric_limits<unsigned int>::max(); static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
private: private:
unsigned int FindFirstFrom(unsigned int blockIndex) const; std::size_t FindFirstFrom(std::size_t blockIndex) const;
Block GetLastBlockMask() const; Block GetLastBlockMask() const;
void ResetExtraBits(); void ResetExtraBits();
static unsigned int ComputeBlockCount(unsigned int bitCount); static std::size_t ComputeBlockCount(std::size_t bitCount);
static unsigned int GetBitIndex(unsigned int bit); static std::size_t GetBitIndex(std::size_t bit);
static unsigned int GetBlockIndex(unsigned int bit); static std::size_t GetBlockIndex(std::size_t bit);
std::vector<Block, Allocator> m_blocks; std::vector<Block, Allocator> m_blocks;
unsigned int m_bitCount; std::size_t m_bitCount;
}; };
template<typename Block, class Allocator> template<typename Block, class Allocator>

View File

@ -42,7 +42,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
Bitset<Block, Allocator>::Bitset(unsigned int bitCount, bool val) : Bitset<Block, Allocator>::Bitset(std::size_t bitCount, bool val) :
Bitset() Bitset()
{ {
Resize(bitCount, val); Resize(bitCount, val);
@ -72,11 +72,11 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
Bitset<Block, Allocator>::Bitset(const char* bits, unsigned int bitCount) : Bitset<Block, Allocator>::Bitset(const char* bits, std::size_t bitCount) :
m_blocks(ComputeBlockCount(bitCount), 0U), m_blocks(ComputeBlockCount(bitCount), 0U),
m_bitCount(bitCount) m_bitCount(bitCount)
{ {
for (unsigned int i = 0; i < bitCount; ++i) for (std::size_t i = 0; i < bitCount; ++i)
{ {
switch (*bits++) switch (*bits++)
{ {
@ -126,7 +126,7 @@ namespace Nz
else else
{ {
// Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits // Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits
for (unsigned int bitPos = 0; bitPos < std::numeric_limits<T>::digits; bitPos++) for (std::size_t bitPos = 0; bitPos < std::numeric_limits<T>::digits; bitPos++)
{ {
if (value & (T(1U) << bitPos)) if (value & (T(1U) << bitPos))
UnboundedSet(bitPos, true); UnboundedSet(bitPos, true);
@ -153,13 +153,13 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::Count() const std::size_t Bitset<Block, Allocator>::Count() const
{ {
if (m_blocks.empty()) if (m_blocks.empty())
return 0; return 0;
unsigned int count = 0; std::size_t count = 0;
for (unsigned int i = 0; i < m_blocks.size(); ++i) for (std::size_t i = 0; i < m_blocks.size(); ++i)
count += CountBits(m_blocks[i]); count += CountBits(m_blocks[i]);
return count; return count;
@ -184,7 +184,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::FindFirst() const std::size_t Bitset<Block, Allocator>::FindFirst() const
{ {
return FindFirstFrom(0); return FindFirstFrom(0);
} }
@ -199,7 +199,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::FindNext(unsigned int bit) const std::size_t Bitset<Block, Allocator>::FindNext(std::size_t bit) const
{ {
NazaraAssert(bit < m_bitCount, "Bit index out of range"); NazaraAssert(bit < m_bitCount, "Bit index out of range");
@ -207,8 +207,8 @@ namespace Nz
return npos; return npos;
// The block of the bit and its index // The block of the bit and its index
unsigned int blockIndex = GetBlockIndex(bit); std::size_t blockIndex = GetBlockIndex(bit);
unsigned int bitIndex = GetBitIndex(bit); std::size_t bitIndex = GetBitIndex(bit);
// We get the block // We get the block
Block block = m_blocks[blockIndex]; Block block = m_blocks[blockIndex];
@ -233,7 +233,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
Block Bitset<Block, Allocator>::GetBlock(unsigned int i) const Block Bitset<Block, Allocator>::GetBlock(std::size_t i) const
{ {
NazaraAssert(i < m_blocks.size(), "Block index out of range"); NazaraAssert(i < m_blocks.size(), "Block index out of range");
@ -246,7 +246,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::GetBlockCount() const std::size_t Bitset<Block, Allocator>::GetBlockCount() const
{ {
return m_blocks.size(); return m_blocks.size();
} }
@ -257,7 +257,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::GetCapacity() const std::size_t Bitset<Block, Allocator>::GetCapacity() const
{ {
return m_blocks.capacity()*bitsPerBlock; return m_blocks.capacity()*bitsPerBlock;
} }
@ -268,7 +268,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::GetSize() const std::size_t Bitset<Block, Allocator>::GetSize() const
{ {
return m_bitCount; return m_bitCount;
} }
@ -285,7 +285,7 @@ namespace Nz
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::PerformsAND(const Bitset& a, const Bitset& b) void Bitset<Block, Allocator>::PerformsAND(const Bitset& a, const Bitset& b)
{ {
std::pair<unsigned int, unsigned int> minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount()); std::pair<std::size_t, std::size_t> minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount());
// We reinitialise our blocks with zero // We reinitialise our blocks with zero
m_blocks.clear(); m_blocks.clear();
@ -293,7 +293,7 @@ namespace Nz
m_bitCount = std::max(a.GetSize(), b.GetSize()); m_bitCount = std::max(a.GetSize(), b.GetSize());
// In case of the "AND", we can stop with the smallest size (because x & 0 = 0) // In case of the "AND", we can stop with the smallest size (because x & 0 = 0)
for (unsigned int i = 0; i < minmax.first; ++i) for (std::size_t i = 0; i < minmax.first; ++i)
m_blocks[i] = a.GetBlock(i) & b.GetBlock(i); m_blocks[i] = a.GetBlock(i) & b.GetBlock(i);
ResetExtraBits(); ResetExtraBits();
@ -311,7 +311,7 @@ namespace Nz
m_blocks.resize(a.GetBlockCount()); m_blocks.resize(a.GetBlockCount());
m_bitCount = a.GetSize(); m_bitCount = a.GetSize();
for (unsigned int i = 0; i < m_blocks.size(); ++i) for (std::size_t i = 0; i < m_blocks.size(); ++i)
m_blocks[i] = ~a.GetBlock(i); m_blocks[i] = ~a.GetBlock(i);
ResetExtraBits(); ResetExtraBits();
@ -329,18 +329,18 @@ namespace Nz
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::PerformsOR(const Bitset& a, const Bitset& b) void Bitset<Block, Allocator>::PerformsOR(const Bitset& a, const Bitset& b)
{ {
const Bitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; const Bitset& greater = (a.GetSize() > b.GetSize()) ? a : b;
const Bitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; const Bitset& lesser = (a.GetSize() > b.GetSize()) ? b : a;
unsigned int maxBlockCount = greater.GetBlockCount(); std::size_t maxBlockCount = greater.GetBlockCount();
unsigned int minBlockCount = lesser.GetBlockCount(); std::size_t minBlockCount = lesser.GetBlockCount();
m_blocks.resize(maxBlockCount); m_blocks.resize(maxBlockCount);
m_bitCount = greater.GetSize(); m_bitCount = greater.GetSize();
for (unsigned int i = 0; i < minBlockCount; ++i) for (std::size_t i = 0; i < minBlockCount; ++i)
m_blocks[i] = a.GetBlock(i) | b.GetBlock(i); m_blocks[i] = a.GetBlock(i) | b.GetBlock(i);
for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) for (std::size_t i = minBlockCount; i < maxBlockCount; ++i)
m_blocks[i] = greater.GetBlock(i); // (x | 0 = x) m_blocks[i] = greater.GetBlock(i); // (x | 0 = x)
ResetExtraBits(); ResetExtraBits();
@ -358,18 +358,18 @@ namespace Nz
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::PerformsXOR(const Bitset& a, const Bitset& b) void Bitset<Block, Allocator>::PerformsXOR(const Bitset& a, const Bitset& b)
{ {
const Bitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; const Bitset& greater = (a.GetSize() > b.GetSize()) ? a : b;
const Bitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; const Bitset& lesser = (a.GetSize() > b.GetSize()) ? b : a;
unsigned int maxBlockCount = greater.GetBlockCount(); std::size_t maxBlockCount = greater.GetBlockCount();
unsigned int minBlockCount = lesser.GetBlockCount(); std::size_t minBlockCount = lesser.GetBlockCount();
m_blocks.resize(maxBlockCount); m_blocks.resize(maxBlockCount);
m_bitCount = greater.GetSize(); m_bitCount = greater.GetSize();
for (unsigned int i = 0; i < minBlockCount; ++i) for (std::size_t i = 0; i < minBlockCount; ++i)
m_blocks[i] = a.GetBlock(i) ^ b.GetBlock(i); m_blocks[i] = a.GetBlock(i) ^ b.GetBlock(i);
for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) for (std::size_t i = minBlockCount; i < maxBlockCount; ++i)
m_blocks[i] = greater.GetBlock(i); // (x ^ 0 = x) m_blocks[i] = greater.GetBlock(i); // (x ^ 0 = x)
ResetExtraBits(); ResetExtraBits();
@ -385,8 +385,8 @@ namespace Nz
bool Bitset<Block, Allocator>::Intersects(const Bitset& bitset) const bool Bitset<Block, Allocator>::Intersects(const Bitset& bitset) const
{ {
// We only test the blocks in common // We only test the blocks in common
unsigned int sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount()); std::size_t sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount());
for (unsigned int i = 0; i < sharedBlocks; ++i) for (std::size_t i = 0; i < sharedBlocks; ++i)
{ {
Block a = GetBlock(i); Block a = GetBlock(i);
Block b = bitset.GetBlock(i); Block b = bitset.GetBlock(i);
@ -404,7 +404,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Reserve(unsigned int bitCount) void Bitset<Block, Allocator>::Reserve(std::size_t bitCount)
{ {
m_blocks.reserve(ComputeBlockCount(bitCount)); m_blocks.reserve(ComputeBlockCount(bitCount));
} }
@ -417,13 +417,13 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Resize(unsigned int bitCount, bool defaultVal) void Bitset<Block, Allocator>::Resize(std::size_t bitCount, bool defaultVal)
{ {
// We begin with changing the size of container, with the correct value of initialisation // We begin with changing the size of container, with the correct value of initialisation
unsigned int lastBlockIndex = m_blocks.size() - 1; std::size_t lastBlockIndex = m_blocks.size() - 1;
m_blocks.resize(ComputeBlockCount(bitCount), (defaultVal) ? fullBitMask : 0U); m_blocks.resize(ComputeBlockCount(bitCount), (defaultVal) ? fullBitMask : 0U);
unsigned int remainingBits = GetBitIndex(m_bitCount); std::size_t remainingBits = GetBitIndex(m_bitCount);
if (bitCount > m_bitCount && remainingBits > 0 && defaultVal) if (bitCount > m_bitCount && remainingBits > 0 && defaultVal)
// Initialisation of unused bits in the last block before the size change // Initialisation of unused bits in the last block before the size change
m_blocks[lastBlockIndex] |= fullBitMask << remainingBits; m_blocks[lastBlockIndex] |= fullBitMask << remainingBits;
@ -451,7 +451,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Reset(unsigned int bit) void Bitset<Block, Allocator>::Reset(std::size_t bit)
{ {
Set(bit, false); Set(bit, false);
} }
@ -482,7 +482,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Set(unsigned int bit, bool val) void Bitset<Block, Allocator>::Set(std::size_t bit, bool val)
{ {
NazaraAssert(bit < m_bitCount, "Bit index out of range"); NazaraAssert(bit < m_bitCount, "Bit index out of range");
@ -503,7 +503,7 @@ namespace Nz
* \remark Produce a NazaraAssert if i is greather than number of blocks in bitset * \remark Produce a NazaraAssert if i is greather than number of blocks in bitset
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::SetBlock(unsigned int i, Block block) void Bitset<Block, Allocator>::SetBlock(std::size_t i, Block block)
{ {
NazaraAssert(i < m_blocks.size(), "Block index out of range"); NazaraAssert(i < m_blocks.size(), "Block index out of range");
@ -537,7 +537,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
bool Bitset<Block, Allocator>::Test(unsigned int bit) const bool Bitset<Block, Allocator>::Test(std::size_t bit) const
{ {
NazaraAssert(bit < m_bitCount, "Bit index out of range"); NazaraAssert(bit < m_bitCount, "Bit index out of range");
@ -555,7 +555,7 @@ namespace Nz
// Special case for the last block // Special case for the last block
Block lastBlockMask = GetLastBlockMask(); Block lastBlockMask = GetLastBlockMask();
for (unsigned int i = 0; i < m_blocks.size(); ++i) for (std::size_t i = 0; i < m_blocks.size(); ++i)
{ {
Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask;
if (m_blocks[i] == mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask if (m_blocks[i] == mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask
@ -576,7 +576,7 @@ namespace Nz
if (m_blocks.empty()) if (m_blocks.empty())
return false; return false;
for (unsigned int i = 0; i < m_blocks.size(); ++i) for (std::size_t i = 0; i < m_blocks.size(); ++i)
{ {
if (m_blocks[i]) if (m_blocks[i])
return true; return true;
@ -612,7 +612,7 @@ namespace Nz
NazaraAssert(m_bitCount <= std::numeric_limits<T>::digits, "Bit count cannot be greater than T bit count"); NazaraAssert(m_bitCount <= std::numeric_limits<T>::digits, "Bit count cannot be greater than T bit count");
T value = 0; T value = 0;
for (unsigned int i = 0; i < m_blocks.size(); ++i) for (std::size_t i = 0; i < m_blocks.size(); ++i)
value |= static_cast<T>(m_blocks[i]) << i*bitsPerBlock; value |= static_cast<T>(m_blocks[i]) << i*bitsPerBlock;
return value; return value;
@ -628,7 +628,7 @@ namespace Nz
{ {
String str(m_bitCount, '0'); String str(m_bitCount, '0');
for (unsigned int i = 0; i < m_bitCount; ++i) for (std::size_t i = 0; i < m_bitCount; ++i)
{ {
if (Test(i)) if (Test(i))
str[m_bitCount - i - 1] = '1'; // Inversion de l'indice str[m_bitCount - i - 1] = '1'; // Inversion de l'indice
@ -648,7 +648,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::UnboundedReset(unsigned int bit) void Bitset<Block, Allocator>::UnboundedReset(std::size_t bit)
{ {
UnboundedSet(bit, false); UnboundedSet(bit, false);
} }
@ -665,7 +665,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::UnboundedSet(unsigned int bit, bool val) void Bitset<Block, Allocator>::UnboundedSet(std::size_t bit, bool val)
{ {
if (bit < m_bitCount) if (bit < m_bitCount)
Set(bit, val); Set(bit, val);
@ -687,7 +687,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
bool Bitset<Block, Allocator>::UnboundedTest(unsigned int bit) const bool Bitset<Block, Allocator>::UnboundedTest(std::size_t bit) const
{ {
if (bit < m_bitCount) if (bit < m_bitCount)
return Test(bit); return Test(bit);
@ -816,13 +816,13 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::FindFirstFrom(unsigned int blockIndex) const std::size_t Bitset<Block, Allocator>::FindFirstFrom(std::size_t blockIndex) const
{ {
if (blockIndex >= m_blocks.size()) if (blockIndex >= m_blocks.size())
return npos; return npos;
// We are looking for the first non-null block // We are looking for the first non-null block
unsigned int i = blockIndex; std::size_t i = blockIndex;
for (; i < m_blocks.size(); ++i) for (; i < m_blocks.size(); ++i)
{ {
if (m_blocks[i]) if (m_blocks[i])
@ -868,7 +868,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::ComputeBlockCount(unsigned int bitCount) std::size_t Bitset<Block, Allocator>::ComputeBlockCount(std::size_t bitCount)
{ {
return GetBlockIndex(bitCount) + ((GetBitIndex(bitCount) != 0U) ? 1U : 0U); return GetBlockIndex(bitCount) + ((GetBitIndex(bitCount) != 0U) ? 1U : 0U);
} }
@ -879,7 +879,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::GetBitIndex(unsigned int bit) std::size_t Bitset<Block, Allocator>::GetBitIndex(std::size_t bit)
{ {
return bit & (bitsPerBlock - 1U); // bit % bitsPerBlock return bit & (bitsPerBlock - 1U); // bit % bitsPerBlock
} }
@ -890,7 +890,7 @@ namespace Nz
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
unsigned int Bitset<Block, Allocator>::GetBlockIndex(unsigned int bit) std::size_t Bitset<Block, Allocator>::GetBlockIndex(std::size_t bit)
{ {
return bit / bitsPerBlock; return bit / bitsPerBlock;
} }
@ -1106,18 +1106,18 @@ namespace Nz
const Bitset<Block, Allocator>& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; const Bitset<Block, Allocator>& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs;
const Bitset<Block, Allocator>& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; const Bitset<Block, Allocator>& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs;
unsigned int maxBlockCount = greater.GetBlockCount(); std::size_t maxBlockCount = greater.GetBlockCount();
unsigned int minBlockCount = lesser.GetBlockCount(); std::size_t minBlockCount = lesser.GetBlockCount();
// We test the blocks in common to check the equality of bits // We test the blocks in common to check the equality of bits
for (unsigned int i = 0; i < minBlockCount; ++i) for (std::size_t i = 0; i < minBlockCount; ++i)
{ {
if (lhs.GetBlock(i) != rhs.GetBlock(i)) if (lhs.GetBlock(i) != rhs.GetBlock(i))
return false; return false;
} }
// Now we check for the blocks that only the biggest bitset owns, and to be equal, they must be set to '0' // Now we check for the blocks that only the biggest bitset owns, and to be equal, they must be set to '0'
for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) for (std::size_t i = minBlockCount; i < maxBlockCount; ++i)
if (greater.GetBlock(i)) if (greater.GetBlock(i))
return false; return false;
@ -1152,20 +1152,20 @@ namespace Nz
const Bitset<Block, Allocator>& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; const Bitset<Block, Allocator>& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs;
const Bitset<Block, Allocator>& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; const Bitset<Block, Allocator>& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs;
unsigned int maxBlockCount = greater.GetBlockCount(); std::size_t maxBlockCount = greater.GetBlockCount();
unsigned int minBlockCount = lesser.GetBlockCount(); std::size_t minBlockCount = lesser.GetBlockCount();
// If the greatest bitset has a single bit active in a block outside the lesser bitset range, then it is greater // If the greatest bitset has a single bit active in a block outside the lesser bitset range, then it is greater
for (unsigned int i = maxBlockCount; i > minBlockCount; ++i) for (std::size_t i = maxBlockCount; i > minBlockCount; ++i)
{ {
if (greater.GetBlock(i)) if (greater.GetBlock(i))
return lhs.GetBlockCount() < rhs.GetBlockCount(); return lhs.GetBlockCount() < rhs.GetBlockCount();
} }
// Compare the common blocks // Compare the common blocks
for (unsigned int i = 0; i < minBlockCount; ++i) for (std::size_t i = 0; i < minBlockCount; ++i)
{ {
unsigned int index = (minBlockCount - i - 1); // Compare from the most significant block to the less significant block std::size_t index = (minBlockCount - i - 1); // Compare from the most significant block to the less significant block
if (lhs.GetBlock(index) < rhs.GetBlock(index)) if (lhs.GetBlock(index) < rhs.GetBlock(index))
return true; return true;
} }

View File

@ -23,10 +23,10 @@ namespace Nz
/*! /*!
* \brief Constructs a ByteArray object with a raw memory and a size * \brief Constructs a ByteArray object with a raw memory and a size
* *
* \param ptr Pointer to raw memory * \param buffer Pointer to raw memory
* \param n Size that can be accessed * \param n Size that can be accessed
* *
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined * \remark If preallocated space of buffer is less than the size, the behaviour is undefined
*/ */
inline ByteArray::ByteArray(const void* buffer, size_type n) : inline ByteArray::ByteArray(const void* buffer, size_type n) :
@ -62,10 +62,10 @@ namespace Nz
/*! /*!
* \brief Appends the content of raw memory * \brief Appends the content of raw memory
* *
* \param ptr Constant pointer to raw memory * \param buffer Constant pointer to raw memory
* \param n Size that can be read * \param n Size that can be read
* *
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined * \remark If preallocated space of buffer is less than the size, the behaviour is undefined
* *
* \see Insert * \see Insert
*/ */
@ -298,11 +298,11 @@ namespace Nz
} }
/*! /*!
* \brief Inserts n times the same value at the iterator position * \brief Inserts n times the same byte at the iterator position
* *
* \param pos Iterator to the position * \param pos Iterator to the position
* \param n Number of repetitions * \param n Number of repetitions
* \param value Value to repeat * \param byte Value to repeat
*/ */
inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte) inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte)
@ -359,10 +359,10 @@ namespace Nz
/*! /*!
* \brief Prepends the content of raw memory * \brief Prepends the content of raw memory
* *
* \param ptr Constant pointer to raw memory * \param buffer Constant pointer to raw memory
* \param n Size that can be read * \param n Size that can be read
* *
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined * \remark If preallocated space of buffer is less than the size, the behaviour is undefined
* *
* \see Insert * \see Insert
*/ */
@ -682,8 +682,7 @@ namespace Nz
* \brief Checks whether the first byte array is equal to the second byte array * \brief Checks whether the first byte array is equal to the second byte array
* \return true if it is the case * \return true if it is the case
* *
* \param first ByteArray to compare in left hand side * \param rhs ByteArray to compare with
* \param second ByteArray to compare in right hand side
*/ */
inline bool ByteArray::operator==(const ByteArray& rhs) const inline bool ByteArray::operator==(const ByteArray& rhs) const
@ -695,8 +694,7 @@ namespace Nz
* \brief Checks whether the first byte array is equal to the second byte array * \brief Checks whether the first byte array is equal to the second byte array
* \return false if it is the case * \return false if it is the case
* *
* \param first ByteArray to compare in left hand side * \param rhs ByteArray to compare with
* \param second ByteArray to compare in right hand side
*/ */
inline bool ByteArray::operator!=(const ByteArray& rhs) const inline bool ByteArray::operator!=(const ByteArray& rhs) const
@ -708,8 +706,7 @@ namespace Nz
* \brief Checks whether the first byte array is less than the second byte array * \brief Checks whether the first byte array is less than the second byte array
* \return true if it is the case * \return true if it is the case
* *
* \param first ByteArray to compare in left hand side * \param rhs ByteArray to compare with
* \param second ByteArray to compare in right hand side
*/ */
inline bool ByteArray::operator<(const ByteArray& rhs) const inline bool ByteArray::operator<(const ByteArray& rhs) const
@ -721,8 +718,7 @@ namespace Nz
* \brief Checks whether the first byte array is less or equal than the second byte array * \brief Checks whether the first byte array is less or equal than the second byte array
* \return true if it is the case * \return true if it is the case
* *
* \param first ByteArray to compare in left hand side * \param rhs ByteArray to compare with
* \param second ByteArray to compare in right hand side
*/ */
inline bool ByteArray::operator<=(const ByteArray& rhs) const inline bool ByteArray::operator<=(const ByteArray& rhs) const
@ -731,11 +727,10 @@ namespace Nz
} }
/*! /*!
* \brief Checks whether the first byte array is greather than the second byte array * \brief Checks whether the first byte array is greater than the second byte array
* \return true if it is the case * \return true if it is the case
* *
* \param first ByteArray to compare in left hand side * \param rhs ByteArray to compare with
* \param second ByteArray to compare in right hand side
*/ */
inline bool ByteArray::operator>(const ByteArray& rhs) const inline bool ByteArray::operator>(const ByteArray& rhs) const
@ -744,11 +739,10 @@ namespace Nz
} }
/*! /*!
* \brief Checks whether the first byte array is greather or equal than the second byte array * \brief Checks whether the first byte array is greater or equal than the second byte array
* \return true if it is the case * \return true if it is the case
* *
* \param first ByteArray to compare in left hand side * \param rhs ByteArray to compare with
* \param second ByteArray to compare in right hand side
*/ */
inline bool ByteArray::operator>=(const ByteArray& rhs) const inline bool ByteArray::operator>=(const ByteArray& rhs) const

View File

@ -25,6 +25,8 @@ namespace Nz
inline Color(const Color& color) = default; inline Color(const Color& color) = default;
inline ~Color() = default; inline ~Color() = default;
inline bool IsOpaque() const;
inline String ToString() const; inline String ToString() const;
inline Color operator+(const Color& angles) const; inline Color operator+(const Color& angles) const;

View File

@ -72,6 +72,15 @@ namespace Nz
{ {
} }
/*!
* \brief Return true is the color has no degree of transparency
* \return true if the color has an alpha value of 255
*/
inline bool Color::IsOpaque() const
{
return a == 255;
}
/*! /*!
* \brief Converts this to string * \brief Converts this to string
* \return String representation of the object "Color(r, g, b[, a])" * \return String representation of the object "Color(r, g, b[, a])"

View File

@ -12,7 +12,7 @@
#include <type_traits> #include <type_traits>
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err) #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// We fore the value of MANAGE_MEMORY in debug // We force the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY
#undef NAZARA_CORE_MANAGE_MEMORY #undef NAZARA_CORE_MANAGE_MEMORY
#define NAZARA_CORE_MANAGE_MEMORY 0 #define NAZARA_CORE_MANAGE_MEMORY 0

View File

@ -33,8 +33,8 @@ namespace Nz
inline void SwapBytes(void* buffer, std::size_t size) inline void SwapBytes(void* buffer, std::size_t size)
{ {
UInt8* bytes = static_cast<UInt8*>(buffer); UInt8* bytes = static_cast<UInt8*>(buffer);
unsigned int i = 0; std::size_t i = 0;
unsigned int j = size - 1; std::size_t j = size - 1;
while (i < j) while (i < j)
std::swap(bytes[i++], bytes[j--]); std::swap(bytes[i++], bytes[j--]);

View File

@ -10,12 +10,29 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup core
* \class Nz::HandledObject<T>
* \brief Core class that represents a handled object
*/
/*!
* \brief Constructs a HandledObject object by assignation
*
* \param object HandledObject to assign into this
*/
template<typename T> template<typename T>
HandledObject<T>::HandledObject(const HandledObject& object) HandledObject<T>::HandledObject(const HandledObject& object)
{ {
NazaraUnused(object);
// Don't copy anything, we're a copy of the object, we have no handle right now // Don't copy anything, we're a copy of the object, we have no handle right now
} }
/*!
* \brief Constructs a HandledObject object by move semantic
*
* \param object HandledObject to move into this
*/
template<typename T> template<typename T>
HandledObject<T>::HandledObject(HandledObject&& object) : HandledObject<T>::HandledObject(HandledObject&& object) :
m_handles(std::move(object.m_handles)) m_handles(std::move(object.m_handles))
@ -24,18 +41,33 @@ namespace Nz
handle->OnObjectMoved(static_cast<T*>(this)); handle->OnObjectMoved(static_cast<T*>(this));
} }
/*!
* \brief Destructs the object and calls UnregisterAllHandles
*
* \see UnregisterAllHandles
*/
template<typename T> template<typename T>
HandledObject<T>::~HandledObject() HandledObject<T>::~HandledObject()
{ {
UnregisterAllHandles(); UnregisterAllHandles();
} }
/*!
* \brief Creates a ObjectHandle for this
* \return ObjectHandle to this
*/
template<typename T> template<typename T>
ObjectHandle<T> HandledObject<T>::CreateHandle() ObjectHandle<T> HandledObject<T>::CreateHandle()
{ {
return ObjectHandle<T>(static_cast<T*>(this)); return ObjectHandle<T>(static_cast<T*>(this));
} }
/*!
* \brief Sets the reference of the HandledObject with the handle from another
* \return A reference to this
*
* \param object The other HandledObject
*/
template<typename T> template<typename T>
HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object) HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object)
{ {
@ -43,6 +75,12 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Moves the HandledObject into this
* \return A reference to this
*
* \param object HandledObject to move in this
*/
template<typename T> template<typename T>
HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object) HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object)
{ {
@ -53,13 +91,22 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Registers a handle
*
* \param handle Handle to register
*
* \remark One handle can only be registered once, errors can occur if it's more than once
*/
template<typename T> template<typename T>
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle) void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
{ {
///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois
m_handles.push_back(handle); m_handles.push_back(handle);
} }
/*!
* \brief Unregisters all handles
*/
template<typename T> template<typename T>
void HandledObject<T>::UnregisterAllHandles() void HandledObject<T>::UnregisterAllHandles()
{ {
@ -70,10 +117,17 @@ namespace Nz
m_handles.clear(); m_handles.clear();
} }
/*!
* \brief Unregisters a handle
*
* \param handle Handle to unregister
*
* \remark One handle can only be unregistered once, crash can occur if it's more than once
* \remark Produces a NazaraAssert if handle not registered
*/
template<typename T> template<typename T>
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept
{ {
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
auto it = std::find(m_handles.begin(), m_handles.end(), handle); auto it = std::find(m_handles.begin(), m_handles.end(), handle);
NazaraAssert(it != m_handles.end(), "Handle not registered"); NazaraAssert(it != m_handles.end(), "Handle not registered");
@ -82,6 +136,14 @@ namespace Nz
m_handles.pop_back(); m_handles.pop_back();
} }
/*!
* \brief Updates one handle with another
*
* \param oldHandle Old handle to replace
* \param newHandle New handle to take place
*
* \remark Produces a NazaraAssert if handle not registered
*/
template<typename T> template<typename T>
void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept
{ {

View File

@ -9,12 +9,26 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup core
* \class Nz::ObjectHandle
* \brief Core class that represents a object handle
*/
/*!
* \brief Constructs a ObjectHandle object by default
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle() : ObjectHandle<T>::ObjectHandle() :
m_object(nullptr) m_object(nullptr)
{ {
} }
/*!
* \brief Constructs a ObjectHandle object with a pointer to an object
*
* \param object Pointer to handle like an object (can be nullptr)
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(T* object) : ObjectHandle<T>::ObjectHandle(T* object) :
ObjectHandle() ObjectHandle()
@ -22,59 +36,97 @@ namespace Nz
Reset(object); Reset(object);
} }
/*!
* \brief Constructs a ObjectHandle object by assignation
*
* \param handle ObjectHandle to assign into this
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) : ObjectHandle<T>::ObjectHandle(const ObjectHandle& handle) :
ObjectHandle() ObjectHandle()
{ {
Reset(handle); Reset(handle);
} }
/*!
* \brief Constructs a ObjectHandle object by move semantic
*
* \param handle ObjectHandle to move into this
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(ObjectHandle<T>&& handle) noexcept : ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept :
ObjectHandle() ObjectHandle()
{ {
Reset(std::move(handle)); Reset(std::move(handle));
} }
/*!
* \brief Destructs the object and calls reset with nullptr
*
* \see Reset
*/
template<typename T> template<typename T>
ObjectHandle<T>::~ObjectHandle() ObjectHandle<T>::~ObjectHandle()
{ {
Reset(nullptr); Reset(nullptr);
} }
/*!
* \brief Gets the underlying object
* \return Underlying object
*/
template<typename T> template<typename T>
T* ObjectHandle<T>::GetObject() const T* ObjectHandle<T>::GetObject() const
{ {
return m_object; return m_object;
} }
/*!
* \brief Checks whether the object is valid
* \return true if object is not nullptr
*/
template<typename T> template<typename T>
bool ObjectHandle<T>::IsValid() const bool ObjectHandle<T>::IsValid() const
{ {
return m_object != nullptr; return m_object != nullptr;
} }
/*!
* \brief Resets the content of the ObjectHandle with another object
*
* \param object Object to handle
*/
template<typename T> template<typename T>
void ObjectHandle<T>::Reset(T* object) void ObjectHandle<T>::Reset(T* object)
{ {
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle // If we already have an entity, we must alert it that we are not pointing to it anymore
if (m_object) if (m_object)
m_object->UnregisterHandle(this); m_object->UnregisterHandle(this);
m_object = object; m_object = object;
if (m_object) if (m_object)
// On informe la nouvelle entité que nous pointons sur elle // We alert the new entity that we are pointing to it
m_object->RegisterHandle(this); m_object->RegisterHandle(this);
} }
/*!
* \brief Resets the content of this with another object
*
* \param handle New object to handle
*/
template<typename T> template<typename T>
void ObjectHandle<T>::Reset(const ObjectHandle<T>& handle) void ObjectHandle<T>::Reset(const ObjectHandle& handle)
{ {
Reset(handle.GetObject()); Reset(handle.GetObject());
} }
/*!
* \brief Resets the content of this with another object by move semantic
*
* \param handle New object to handle to move into this
*/
template<typename T> template<typename T>
void ObjectHandle<T>::Reset(ObjectHandle<T>&& handle) noexcept void ObjectHandle<T>::Reset(ObjectHandle&& handle) noexcept
{ {
if (m_object) if (m_object)
m_object->UnregisterHandle(this); m_object->UnregisterHandle(this);
@ -87,12 +139,18 @@ namespace Nz
} }
} }
/*!
* \brief Swaps the content of the two ObjectHandle
* \return A reference to this
*
* \param handle ObjectHandle to swap
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle) ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle& handle)
{ {
// Comme nous inversons les handles, nous devons prévenir les entités // As we swap the two handles, we must alert the entities
// La version par défaut de swap (à base de move) aurait fonctionné, // The default version with swap (move) would be working,
// mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire). // but will register handles one more time (due to temporary copy).
if (m_object) if (m_object)
{ {
m_object->UnregisterHandle(this); m_object->UnregisterHandle(this);
@ -105,11 +163,15 @@ namespace Nz
handle.m_object->RegisterHandle(this); handle.m_object->RegisterHandle(this);
} }
// On effectue l'échange // We do the swap
std::swap(m_object, handle.m_object); std::swap(m_object, handle.m_object);
return *this; return *this;
} }
/*!
* \brief Gives a string representation
* \return A string representation of the object "ObjectHandle(object representation) or Null"
*/
template<typename T> template<typename T>
Nz::String ObjectHandle<T>::ToString() const Nz::String ObjectHandle<T>::ToString() const
{ {
@ -125,24 +187,44 @@ namespace Nz
return ss; return ss;
} }
/*!
* \brief Converts the ObjectHandle to bool
* \return true if reference is not nullptr
*
* \see IsValid
*/
template<typename T> template<typename T>
ObjectHandle<T>::operator bool() const ObjectHandle<T>::operator bool() const
{ {
return IsValid(); return IsValid();
} }
/*!
* \brief Dereferences the ObjectHandle
* \return Underlying pointer
*/
template<typename T> template<typename T>
ObjectHandle<T>::operator T*() const ObjectHandle<T>::operator T*() const
{ {
return m_object; return m_object;
} }
/*!
* \brief Dereferences the ObjectHandle
* \return Underlying pointer
*/
template<typename T> template<typename T>
T* ObjectHandle<T>::operator->() const T* ObjectHandle<T>::operator->() const
{ {
return m_object; return m_object;
} }
/*!
* \brief Assigns the entity into this
* \return A reference to this
*
* \param entity Pointer to handle like an object (can be nullptr)
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity) ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
{ {
@ -151,22 +233,37 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Sets the handle of the ObjectHandle with the handle from another
* \return A reference to this
*
* \param handle The other ObjectHandle
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle<T>& handle) ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle& handle)
{ {
Reset(handle); Reset(handle);
return *this; return *this;
} }
/*!
* \brief Moves the ObjectHandle into this
* \return A reference to this
*
* \param handle ObjectHandle to move in this
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle<T>&& handle) noexcept ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle&& handle) noexcept
{ {
Reset(std::move(handle)); Reset(std::move(handle));
return *this; return *this;
} }
/*!
* \brief Action to do on object destruction
*/
template<typename T> template<typename T>
void ObjectHandle<T>::OnObjectDestroyed() void ObjectHandle<T>::OnObjectDestroyed()
{ {
@ -174,6 +271,9 @@ namespace Nz
m_object = nullptr; m_object = nullptr;
} }
/*!
* \brief Action to do on object move
*/
template<typename T> template<typename T>
void ObjectHandle<T>::OnObjectMoved(T* newObject) void ObjectHandle<T>::OnObjectMoved(T* newObject)
{ {
@ -181,114 +281,248 @@ namespace Nz
m_object = newObject; m_object = newObject;
} }
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param handle The ObjectHandle to output
*/
template<typename T> template<typename T>
std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle) std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle)
{ {
return handle.ToString(); out << handle.ToString();
return out;
} }
/*!
* \brief Checks whether the first object handle is equal to the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return lhs.GetObject() == rhs.GetObject(); return lhs.GetObject() == rhs.GetObject();
} }
/*!
* \brief Checks whether the object is equal to the second object handle
* \return true if it is the case
*
* \param lhs Object to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator==(const T& lhs, const ObjectHandle<T>& rhs) bool operator==(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return &lhs == rhs.GetObject(); return &lhs == rhs.GetObject();
} }
/*!
* \brief Checks whether the object handle is equal to the second object
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs Object to compare in right hand side
*/
template<typename T> template<typename T>
bool operator==(const ObjectHandle<T>& lhs, const T& rhs) bool operator==(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return lhs.GetObject() == &rhs; return lhs.GetObject() == &rhs;
} }
/*!
* \brief Checks whether the first object handle is equal to the second object handle
* \return false if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/*!
* \brief Checks whether the object is equal to the second object handle
* \return false if it is the case
*
* \param lhs Object to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator!=(const T& lhs, const ObjectHandle<T>& rhs) bool operator!=(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/*!
* \brief Checks whether the object handle is equal to the second object
* \return false if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs Object to compare in right hand side
*/
template<typename T> template<typename T>
bool operator!=(const ObjectHandle<T>& lhs, const T& rhs) bool operator!=(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return lhs.m_object < rhs.m_object; return lhs.m_object < rhs.m_object;
} }
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<(const T& lhs, const ObjectHandle<T>& rhs) bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return &lhs < rhs.m_object; return &lhs < rhs.m_object;
} }
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<(const ObjectHandle<T>& lhs, const T& rhs) bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return lhs.m_object < &rhs; return lhs.m_object < &rhs;
} }
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<=(const T& lhs, const ObjectHandle<T>& rhs) bool operator<=(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<=(const ObjectHandle<T>& lhs, const T& rhs) bool operator<=(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>(const T& lhs, const ObjectHandle<T>& rhs) bool operator>(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>(const ObjectHandle<T>& lhs, const T& rhs) bool operator>(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs < rhs); return !(lhs < rhs);
} }
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>=(const T& lhs, const ObjectHandle<T>& rhs) bool operator>=(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs < rhs); return !(lhs < rhs);
} }
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectHandle to compare in left hand side
* \param rhs ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>=(const ObjectHandle<T>& lhs, const T& rhs) bool operator>=(const ObjectHandle<T>& lhs, const T& rhs)
{ {
@ -301,6 +535,12 @@ namespace Nz
namespace std namespace std
{ {
/*!
* \brief Swaps two ObjectHandle, specialisation of std
*
* \param lhs First object handle
* \param rhs Second object handle
*/
template<typename T> template<typename T>
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs) void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs)
{ {

View File

@ -17,8 +17,6 @@ namespace Nz
template<typename T> template<typename T>
class ObjectRef class ObjectRef
{ {
static_assert(std::is_base_of<RefCounted, T>::value, "ObjectRef shall only be used with RefCounted-derived type");
public: public:
ObjectRef(); ObjectRef();
ObjectRef(T* object); ObjectRef(T* object);
@ -46,8 +44,33 @@ namespace Nz
T* m_object; T* m_object;
}; };
template<typename T> struct PointedType<ObjectRef<T>> {typedef T type;}; template<typename T> bool operator==(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs);
template<typename T> struct PointedType<ObjectRef<T> const> {typedef T type;}; template<typename T> bool operator==(const T& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator==(const ObjectRef<T>& lhs, const T& rhs);
template<typename T> bool operator!=(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator!=(const T& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator!=(const ObjectRef<T>& lhs, const T& rhs);
template<typename T> bool operator<(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator<(const T& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator<(const ObjectRef<T>& lhs, const T& rhs);
template<typename T> bool operator<=(const ObjectRef<T>, const ObjectRef<T>& rhs);
template<typename T> bool operator<=(const T& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator<=(const ObjectRef<T>& lhs, const T& rhs);
template<typename T> bool operator>(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator>(const T& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator>(const ObjectRef<T>& lhs, const T& rhs);
template<typename T> bool operator>=(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator>=(const T& lhs, const ObjectRef<T>& rhs);
template<typename T> bool operator>=(const ObjectRef<T>& lhs, const T& rhs);
template<typename T> struct PointedType<ObjectRef<T>> { typedef T type; };
template<typename T> struct PointedType<ObjectRef<T> const> { typedef T type; };
} }
#include <Nazara/Core/ObjectRef.inl> #include <Nazara/Core/ObjectRef.inl>

View File

@ -245,6 +245,241 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Checks whether the first object handle is equal to the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator==(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return lhs.Get() == rhs.Get();
}
/*!
* \brief Checks whether the object is equal to the second object handle
* \return true if it is the case
*
* \param lhs Object to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator==(const T& lhs, const ObjectRef<T>& rhs)
{
return &lhs == rhs.Get();
}
/*!
* \brief Checks whether the object handle is equal to the second object
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs Object to compare in right hand side
*/
template<typename T>
bool operator==(const ObjectRef<T>& lhs, const T& rhs)
{
return lhs.Get() == &rhs;
}
/*!
* \brief Checks whether the first object handle is equal to the second object handle
* \return false if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator!=(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return !(lhs == rhs);
}
/*!
* \brief Checks whether the object is equal to the second object handle
* \return false if it is the case
*
* \param lhs Object to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator!=(const T& lhs, const ObjectRef<T>& rhs)
{
return !(lhs == rhs);
}
/*!
* \brief Checks whether the object handle is equal to the second object
* \return false if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs Object to compare in right hand side
*/
template<typename T>
bool operator!=(const ObjectRef<T>& lhs, const T& rhs)
{
return !(lhs == rhs);
}
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator<(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return lhs.m_object < rhs.m_object;
}
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator<(const T& lhs, const ObjectRef<T>& rhs)
{
return &lhs < rhs.m_object;
}
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator<(const ObjectRef<T>& lhs, const T& rhs)
{
return lhs.m_object < &rhs;
}
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator<=(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return !(lhs > rhs);
}
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator<=(const T& lhs, const ObjectRef<T>& rhs)
{
return !(lhs > rhs);
}
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator<=(const ObjectRef<T>& lhs, const T& rhs)
{
return !(lhs > rhs);
}
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator>(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return rhs < lhs;
}
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator>(const T& lhs, const ObjectRef<T>& rhs)
{
return rhs < lhs;
}
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator>(const ObjectRef<T>& lhs, const T& rhs)
{
return rhs < lhs;
}
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator>=(const ObjectRef<T>& lhs, const ObjectRef<T>& rhs)
{
return !(lhs < rhs);
}
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator>=(const T& lhs, const ObjectRef<T>& rhs)
{
return !(lhs < rhs);
}
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param lhs ObjectRef to compare in left hand side
* \param rhs ObjectRef to compare in right hand side
*/
template<typename T>
bool operator>=(const ObjectRef<T>& lhs, const T& rhs)
{
return !(lhs < rhs);
}
} }
namespace std namespace std

View File

@ -50,6 +50,8 @@ namespace Nz
void SetParameter(const String& name, void* value); void SetParameter(const String& name, void* value);
void SetParameter(const String& name, void* value, Destructor destructor); void SetParameter(const String& name, void* value, Destructor destructor);
String ToString() const;
ParameterList& operator=(const ParameterList& list); ParameterList& operator=(const ParameterList& list);
ParameterList& operator=(ParameterList&&) = default; ParameterList& operator=(ParameterList&&) = default;
@ -73,7 +75,7 @@ namespace Nz
ParameterType type; ParameterType type;
union Value union Value
{ {
// On définit un constructeur/destructeur vide, permettant de mettre des classes dans l'union // We define an empty constructor/destructor, to be able to put classes in the union
Value() {} Value() {}
Value(const Value&) {} // Placeholder Value(const Value&) {} // Placeholder
~Value() {} ~Value() {}
@ -98,4 +100,6 @@ namespace Nz
}; };
} }
std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList);
#endif // NAZARA_PARAMETERLIST_HPP #endif // NAZARA_PARAMETERLIST_HPP

View File

@ -39,7 +39,7 @@ namespace Nz
static bool IsExtensionSupported(const String& extension); static bool IsExtensionSupported(const String& extension);
static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters()); static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters());
static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); static bool LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters = Parameters());
static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters()); static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters());
static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr);

View File

@ -66,7 +66,7 @@ namespace Nz
return false; return false;
} }
File file(path); // Ouvert seulement en cas de besoin File file(path); // Open only if needed
bool found = false; bool found = false;
for (Loader& loader : Type::s_loaders) for (Loader& loader : Type::s_loaders)
@ -160,7 +160,7 @@ namespace Nz
* \remark Produces a NazaraError if all loaders failed or no loader was found * \remark Produces a NazaraError if all loaders failed or no loader was found
*/ */
template<typename Type, typename Parameters> template<typename Type, typename Parameters>
bool ResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) bool ResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters)
{ {
NazaraAssert(resource, "Invalid resource"); NazaraAssert(resource, "Invalid resource");
NazaraAssert(data, "Invalid data pointer"); NazaraAssert(data, "Invalid data pointer");

View File

@ -48,7 +48,7 @@ namespace Nz
* \remark The previous file content will be discarded, to prevent this behavior you should use SaveToStream * \remark The previous file content will be discarded, to prevent this behavior you should use SaveToStream
* \remark The file extension will be used as format for the saver ("image.png" => "png", to write a specified format to a user-specified extension you should use SaveToStream * \remark The file extension will be used as format for the saver ("image.png" => "png", to write a specified format to a user-specified extension you should use SaveToStream
* *
* \seealso SaveToStream * \see SaveToStream
*/ */
template<typename Type, typename Parameters> template<typename Type, typename Parameters>
bool ResourceSaver<Type, Parameters>::SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters) bool ResourceSaver<Type, Parameters>::SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters)
@ -84,7 +84,7 @@ namespace Nz
} }
else else
{ {
if (!file.Open(OpenMode_WriteOnly)) if (!file.Open(OpenMode_WriteOnly | OpenMode_Truncate))
{ {
NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode"); NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode");
return false; return false;
@ -114,7 +114,7 @@ namespace Nz
* \param format Data format to save the resource to * \param format Data format to save the resource to
* \param parameters Parameters for the saving * \param parameters Parameters for the saving
* *
* \seealso SaveToFile * \see SaveToFile
*/ */
template<typename Type, typename Parameters> template<typename Type, typename Parameters>
bool ResourceSaver<Type, Parameters>::SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters) bool ResourceSaver<Type, Parameters>::SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters)

View File

@ -84,16 +84,15 @@ namespace Nz
namespace std namespace std
{ {
template<>
struct hash<Nz::String>
{
/*! /*!
* \brief Specialisation of std to hash * \brief Specialisation of std to hash
* \return Result of the hash * \return Result of the hash
* *
* \param str String to hash * \param str String to hash
*/ */
template<>
struct hash<Nz::String>
{
size_t operator()(const Nz::String& str) const size_t operator()(const Nz::String& str) const
{ {
// Algorithme DJB2 // Algorithme DJB2

View File

@ -22,6 +22,10 @@ namespace Nz
StringStream(const StringStream&) = default; StringStream(const StringStream&) = default;
StringStream(StringStream&&) noexcept = default; StringStream(StringStream&&) noexcept = default;
void Clear();
std::size_t GetBufferSize() const;
String ToString() const; String ToString() const;
StringStream& operator=(const StringStream&) = default; StringStream& operator=(const StringStream&) = default;

View File

@ -1,4 +1,4 @@
// This file was automatically generated on 17 Nov 2015 at 13:20:45 // This file was automatically generated on 20 Jul 2016 at 13:49:17
/* /*
Nazara Engine - Graphics module Nazara Engine - Graphics module
@ -47,6 +47,8 @@
#include <Nazara/Graphics/DeferredRenderPass.hpp> #include <Nazara/Graphics/DeferredRenderPass.hpp>
#include <Nazara/Graphics/DeferredRenderQueue.hpp> #include <Nazara/Graphics/DeferredRenderQueue.hpp>
#include <Nazara/Graphics/DeferredRenderTechnique.hpp> #include <Nazara/Graphics/DeferredRenderTechnique.hpp>
#include <Nazara/Graphics/DepthRenderQueue.hpp>
#include <Nazara/Graphics/DepthRenderTechnique.hpp>
#include <Nazara/Graphics/Drawable.hpp> #include <Nazara/Graphics/Drawable.hpp>
#include <Nazara/Graphics/Enums.hpp> #include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/ForwardRenderQueue.hpp> #include <Nazara/Graphics/ForwardRenderQueue.hpp>
@ -61,11 +63,12 @@
#include <Nazara/Graphics/ParticleDeclaration.hpp> #include <Nazara/Graphics/ParticleDeclaration.hpp>
#include <Nazara/Graphics/ParticleEmitter.hpp> #include <Nazara/Graphics/ParticleEmitter.hpp>
#include <Nazara/Graphics/ParticleGenerator.hpp> #include <Nazara/Graphics/ParticleGenerator.hpp>
#include <Nazara/Graphics/ParticleGroup.hpp>
#include <Nazara/Graphics/ParticleMapper.hpp> #include <Nazara/Graphics/ParticleMapper.hpp>
#include <Nazara/Graphics/ParticleRenderer.hpp> #include <Nazara/Graphics/ParticleRenderer.hpp>
#include <Nazara/Graphics/ParticleStruct.hpp> #include <Nazara/Graphics/ParticleStruct.hpp>
#include <Nazara/Graphics/ParticleSystem.hpp>
#include <Nazara/Graphics/Renderable.hpp> #include <Nazara/Graphics/Renderable.hpp>
#include <Nazara/Graphics/MaterialPipeline.hpp>
#include <Nazara/Graphics/RenderTechniques.hpp> #include <Nazara/Graphics/RenderTechniques.hpp>
#include <Nazara/Graphics/SceneData.hpp> #include <Nazara/Graphics/SceneData.hpp>
#include <Nazara/Graphics/SkeletalModel.hpp> #include <Nazara/Graphics/SkeletalModel.hpp>

View File

@ -38,7 +38,6 @@ namespace Nz
// Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards,
// mais je n'ai pas d'autre solution tout aussi performante pour le moment... // mais je n'ai pas d'autre solution tout aussi performante pour le moment...
virtual void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) = 0;
virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr = nullptr, SparsePtr<const Color> colorPtr = nullptr) = 0; virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr = nullptr, SparsePtr<const Color> colorPtr = nullptr) = 0;
virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr) = 0; virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr) = 0;
virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr = nullptr) = 0; virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr = nullptr) = 0;
@ -62,7 +61,9 @@ namespace Nz
struct DirectionalLight struct DirectionalLight
{ {
Color color; Color color;
Matrix4f transformMatrix;
Vector3f direction; Vector3f direction;
Texture* shadowMap;
float ambientFactor; float ambientFactor;
float diffuseFactor; float diffuseFactor;
}; };
@ -71,6 +72,7 @@ namespace Nz
{ {
Color color; Color color;
Vector3f position; Vector3f position;
Texture* shadowMap;
float ambientFactor; float ambientFactor;
float attenuation; float attenuation;
float diffuseFactor; float diffuseFactor;
@ -81,8 +83,10 @@ namespace Nz
struct SpotLight struct SpotLight
{ {
Color color; Color color;
Matrix4f transformMatrix;
Vector3f direction; Vector3f direction;
Vector3f position; Vector3f position;
Texture* shadowMap;
float ambientFactor; float ambientFactor;
float attenuation; float attenuation;
float diffuseFactor; float diffuseFactor;

View File

@ -7,6 +7,10 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a Billboard object by default
*/
inline Billboard::Billboard() inline Billboard::Billboard()
{ {
SetColor(Color::White); SetColor(Color::White);
@ -15,6 +19,12 @@ namespace Nz
SetSize(64.f, 64.f); SetSize(64.f, 64.f);
} }
/*!
* \brief Constructs a Billboard object with a reference to a material
*
* \param material Reference to a material
*/
inline Billboard::Billboard(MaterialRef material) inline Billboard::Billboard(MaterialRef material)
{ {
SetColor(Color::White); SetColor(Color::White);
@ -23,6 +33,12 @@ namespace Nz
SetSize(64.f, 64.f); SetSize(64.f, 64.f);
} }
/*!
* \brief Constructs a Billboard object with a pointer to a texture
*
* \param texture Pointer to a texture
*/
inline Billboard::Billboard(Texture* texture) inline Billboard::Billboard(Texture* texture)
{ {
SetColor(Color::White); SetColor(Color::White);
@ -31,6 +47,12 @@ namespace Nz
SetTexture(texture, true); SetTexture(texture, true);
} }
/*!
* \brief Constructs a Billboard object by assignation
*
* \param billboard Billboard to copy into this
*/
inline Billboard::Billboard(const Billboard& billboard) : inline Billboard::Billboard(const Billboard& billboard) :
InstancedRenderable(billboard), InstancedRenderable(billboard),
m_color(billboard.m_color), m_color(billboard.m_color),
@ -41,40 +63,76 @@ namespace Nz
{ {
} }
/*!
* \brief Gets the color of the billboard
* \return Current color
*/
inline const Color& Billboard::GetColor() const inline const Color& Billboard::GetColor() const
{ {
return m_color; return m_color;
} }
/*!
* \brief Gets the material of the billboard
* \return Current material
*/
inline const MaterialRef& Billboard::GetMaterial() const inline const MaterialRef& Billboard::GetMaterial() const
{ {
return m_material; return m_material;
} }
/*!
* \brief Gets the rotation of the billboard
* \return Current rotation
*/
inline float Billboard::GetRotation() const inline float Billboard::GetRotation() const
{ {
return m_rotation; return m_rotation;
} }
/*!
* \brief Gets the size of the billboard
* \return Current size
*/
inline const Vector2f& Billboard::GetSize() const inline const Vector2f& Billboard::GetSize() const
{ {
return m_size; return m_size;
} }
/*!
* \brief Sets the color of the billboard
*
* \param color Color for the billboard
*/
inline void Billboard::SetColor(const Color& color) inline void Billboard::SetColor(const Color& color)
{ {
m_color = color; m_color = color;
} }
/*!
* \brief Sets the default material of the billboard (just default material)
*/
inline void Billboard::SetDefaultMaterial() inline void Billboard::SetDefaultMaterial()
{ {
MaterialRef material = Material::New(); MaterialRef material = Material::New();
material->Enable(RendererParameter_FaceCulling, true); material->EnableFaceCulling(true);
material->EnableLighting(false);
SetMaterial(std::move(material)); SetMaterial(std::move(material));
} }
/*!
* \brief Sets the material of the billboard
*
* \param material Material for the billboard
* \param resizeBillboard Should billboard be resized to the material size (diffuse map)
*/
inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard) inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard)
{ {
m_material = std::move(material); m_material = std::move(material);
@ -86,25 +144,51 @@ namespace Nz
} }
} }
/*!
* \brief Sets the rotation of the billboard
*
* \param rotation Rotation for the billboard
*/
inline void Billboard::SetRotation(float rotation) inline void Billboard::SetRotation(float rotation)
{ {
m_rotation = rotation; m_rotation = rotation;
m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation)); m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation));
} }
/*!
* \brief Sets the size of the billboard
*
* \param size Size for the billboard
*/
inline void Billboard::SetSize(const Vector2f& size) inline void Billboard::SetSize(const Vector2f& size)
{ {
m_size = size; m_size = size;
// On invalide la bounding box // We invalidate the bounding volume
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
/*!
* \brief Sets the size of the billboard
*
* \param sizeX Size in X for the billboard
* \param sizeY Size in Y for the billboard
*/
inline void Billboard::SetSize(float sizeX, float sizeY) inline void Billboard::SetSize(float sizeX, float sizeY)
{ {
SetSize(Vector2f(sizeX, sizeY)); SetSize(Vector2f(sizeX, sizeY));
} }
/*!
* \brief Sets the texture of the billboard
*
* \param texture Texture for the billboard
* \param resizeBillboard Should billboard be resized to the texture size
*/
inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard) inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard)
{ {
if (!m_material) if (!m_material)
@ -118,6 +202,13 @@ namespace Nz
m_material->SetDiffuseMap(std::move(texture)); m_material->SetDiffuseMap(std::move(texture));
} }
/*!
* \brief Sets the current billboard with the content of the other one
* \return A reference to this
*
* \param billboard The other Billboard
*/
inline Billboard& Billboard::operator=(const Billboard& billboard) inline Billboard& Billboard::operator=(const Billboard& billboard)
{ {
InstancedRenderable::operator=(billboard); InstancedRenderable::operator=(billboard);
@ -131,6 +222,13 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Creates a new billboard from the arguments
* \return A reference to the newly created billboard
*
* \param args Arguments for the billboard
*/
template<typename... Args> template<typename... Args>
BillboardRef Billboard::New(Args&&... args) BillboardRef Billboard::New(Args&&... args)
{ {

View File

@ -7,6 +7,13 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Creates a new color background from the arguments
* \return A reference to the newly created color background
*
* \param args Arguments for the color background
*/
template<typename... Args> template<typename... Args>
ColorBackgroundRef ColorBackground::New(Args&&... args) ColorBackgroundRef ColorBackground::New(Args&&... args)
{ {

Some files were not shown because too many files have changed in this diff Show More