From d2584b7c33f7e36fd5d2eea009b306b7494118d6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Dec 2015 15:11:57 +0100 Subject: [PATCH 001/229] Lua: Add support for default arguments Former-commit-id: a319bcadf39b7e1633aaa23f360059a1f7449590 --- include/Nazara/Lua/LuaClass.hpp | 7 +- include/Nazara/Lua/LuaClass.inl | 24 +-- include/Nazara/Lua/LuaInstance.hpp | 3 +- include/Nazara/Lua/LuaInstance.inl | 317 ++++++++++++++++++++--------- 4 files changed, 244 insertions(+), 107 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 96e271a31..fe592a4aa 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -42,12 +42,13 @@ namespace Nz void SetFinalizer(FinalizerFunc finalizer); void SetGetter(ClassIndexFunc getter); void SetMethod(const String& name, ClassFunc method); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...)); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); + void SetBindMode(LuaBindMode mode); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); - template void SetStaticMethod(const String& name, R(*func)(Args...)); + template void SetStaticMethod(const String& name, R(*func)(Args...), DefArgs... defArgs); void SetStaticSetter(StaticIndexFunc getter); private: diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 545fa08ba..b49dd5dcc 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -176,12 +176,12 @@ namespace Nz } template - template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...)) + template + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) { - SetMethod(name, [func] (LuaInstance& instance, T& object) -> int + SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int { - LuaImplMethodProxy handler(instance, object); + LuaImplMethodProxy::Impl handler(instance, object, defArgs...); handler.ProcessArgs(); return handler.Invoke(func); @@ -189,12 +189,12 @@ namespace Nz } template - template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const) + template + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs) { - SetMethod(name, [func] (LuaInstance& instance, T& object) -> int + SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int { - LuaImplMethodProxy handler(instance, object); + LuaImplMethodProxy::Impl handler(instance, object, defArgs...); handler.ProcessArgs(); return handler.Invoke(func); @@ -220,12 +220,12 @@ namespace Nz } template - template - void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...)) + template + void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...), DefArgs... defArgs) { - SetStaticMethod(name, [func] (LuaInstance& instance) -> int + SetStaticMethod(name, [func, defArgs...] (LuaInstance& instance) -> int { - LuaImplFunctionProxy handler(instance); + LuaImplFunctionProxy::Impl handler(instance); handler.ProcessArgs(); return handler.Invoke(func); diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 3a725472a..cdf728c62 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -43,6 +43,7 @@ namespace Nz bool Call(unsigned int argCount, unsigned int resultCount); template T Check(int index); + template T Check(int index, T defValue); void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; @@ -115,7 +116,7 @@ namespace Nz void PushBoolean(bool value); void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); void PushFunction(LuaFunction func); - template void PushFunction(R(*func)(Args...)); + template void PushFunction(R(*func)(Args...), DefArgs... defArgs); void PushInteger(long long value); void PushLightUserdata(void* value); void PushMetatable(const char* str); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index c2153a4e1..8c0f40ac4 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -4,6 +4,7 @@ #include #include +#include namespace Nz { @@ -13,32 +14,68 @@ namespace Nz return instance.CheckBoolean(index); } + inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int index, bool defValue, TypeTag) + { + return instance.CheckBoolean(index, defValue); + } + inline double LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { return instance.CheckNumber(index); } + inline double LuaImplQueryArg(LuaInstance& instance, unsigned int index, double defValue, TypeTag) + { + return instance.CheckNumber(index, defValue); + } + inline float LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { return static_cast(instance.CheckNumber(index)); } + inline float LuaImplQueryArg(LuaInstance& instance, unsigned int index, float defValue, TypeTag) + { + return static_cast(instance.CheckNumber(index, defValue)); + } + template std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); } + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, T defValue, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); + } + template std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { return static_cast(instance.CheckInteger(index)); } + template + std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, T defValue, TypeTag) + { + return static_cast(instance.CheckInteger(index, defValue)); + } + template std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { - return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); + using SignedT = std::make_signed_t; + return static_cast(LuaImplQueryArg(instance, index, TypeTag())); + } + + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, T defValue, TypeTag) + { + using SignedT = std::make_signed_t; + return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); } inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) @@ -49,6 +86,14 @@ namespace Nz return std::string(str, strLength); } + inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, const std::string& defValue, TypeTag) + { + std::size_t strLength = 0; + const char* str = instance.CheckString(index, defValue.c_str(), &strLength); + + return std::string(str, strLength); + } + inline String LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { std::size_t strLength = 0; @@ -57,12 +102,35 @@ namespace Nz return String(str, strLength); } + inline String LuaImplQueryArg(LuaInstance& instance, unsigned int index, const String& defValue, TypeTag) + { + std::size_t strLength = 0; + const char* str = instance.CheckString(index, defValue.GetConstBuffer(), &strLength); + + return String(str, strLength); + } + template T LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { return LuaImplQueryArg(instance, index, TypeTag()); } + template + T LuaImplQueryArg(LuaInstance& instance, unsigned int index, const T& defValue, TypeTag tag) + { + if (instance.IsValid(index)) + return LuaImplQueryArg(instance, index, tag); + else + return defValue; + } + + template + T LuaImplQueryArg(LuaInstance& instance, unsigned int index, const T& defValue, TypeTag) + { + return LuaImplQueryArg(instance, index, defValue, TypeTag()); + } + // Function returns inline int LuaImplReplyVal(LuaInstance& instance, bool val, TypeTag) { @@ -128,120 +196,181 @@ namespace Nz return retVal; } + template + struct LuaImplArgProcesser; + + template<> + struct LuaImplArgProcesser + { + template + static void Process(LuaInstance& instance, ArgContainer& args, DefArgContainer& defArgs) + { + std::get(args) = std::move(LuaImplQueryArg(instance, N + 1, std::get(defArgs), TypeTag())); + } + }; + + template<> + struct LuaImplArgProcesser + { + template + static void Process(LuaInstance& instance, ArgContainer& args, DefArgContainer& defArgs) + { + NazaraUnused(defArgs); + + std::get(args) = std::move(LuaImplQueryArg(instance, N + 1, TypeTag())); + } + }; + template class LuaImplFunctionProxy { public: - LuaImplFunctionProxy(LuaInstance& instance) : - m_instance(instance) + template + class Impl { - } + static constexpr std::size_t ArgCount = sizeof...(Args); + static constexpr std::size_t DefArgCount = sizeof...(DefArgs); - template - void ProcessArgs() - { - // No argument to process - } + static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument"); - template - void ProcessArgs() - { - std::get(m_args) = std::move(LuaImplQueryArg(m_instance, N+1, TypeTag())); - } + static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; - template - void ProcessArgs() - { - ProcessArgs(); - ProcessArgs(); - } + public: + Impl(LuaInstance& instance, DefArgs... defArgs) : + m_defaultArgs(std::forward(defArgs)...), + m_instance(instance), + { + } - void ProcessArgs() - { - ProcessArgs<0, Args...>(); - } + void ProcessArgs() + { + ProcessArgs<0, Args...>(); + } - int Invoke(void (*func)(Args...)) - { - Apply(func, m_args); - return 0; - } + int Invoke(void (*func)(Args...)) + { + Apply(func, m_args); + return 0; + } - template - int Invoke(Ret (*func)(Args...)) - { - return LuaImplReplyVal(m_instance, std::move(Apply(func, m_args)), TypeTag()); - } + template + int Invoke(Ret (*func)(Args...)) + { + return LuaImplReplyVal(m_instance, std::move(Apply(func, m_args)), TypeTag()); + } - private: - std::tuple>...> m_args; - LuaInstance& m_instance; + private: + using ArgContainer = std::tuple>...>; + using DefArgContainer = std::tuple>...>; + + template + void ProcessArgs() + { + // No argument to process + } + + template + void ProcessArgs() + { + using CheckDefValue = typename std::integral_constant= FirstDefArg>; + LuaImplArgProcesser::Process(m_instance, m_args, m_defaultArgs); + } + + template + void ProcessArgs() + { + ProcessArgs(); + ProcessArgs(); + } + + ArgContainer m_args; + DefArgContainer m_defaultArgs; + LuaInstance& m_instance; + }; }; template class LuaImplMethodProxy { public: - LuaImplMethodProxy(LuaInstance& instance, T& object) : - m_instance(instance), - m_object(object) + template + class Impl { - } + static constexpr std::size_t ArgCount = sizeof...(Args); + static constexpr std::size_t DefArgCount = sizeof...(DefArgs); - template - void ProcessArgs() - { - // No argument to process - } + static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument"); - template - void ProcessArgs() - { - std::get(m_args) = std::move(LuaImplQueryArg(m_instance, N + 1, TypeTag())); - } + static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; - template - void ProcessArgs() - { - ProcessArgs(); - ProcessArgs(); - } + public: + Impl(LuaInstance& instance, T& object, DefArgs... defArgs) : + m_defaultArgs(std::forward(defArgs)...), + m_instance(instance), + m_object(object) + { + } - void ProcessArgs() - { - ProcessArgs<0, Args...>(); - } + void ProcessArgs() + { + ProcessArgs<0, Args...>(); + } - template - std::enable_if_t::value, int> Invoke(void(P::*func)(Args...)) - { - Apply(m_object, func, m_args); - return 0; - } + template + std::enable_if_t::value, int> Invoke(void(P::*func)(Args...)) + { + Apply(m_object, func, m_args); + return 0; + } - template - std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...)) - { - return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); - } + template + std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...)) + { + return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + } - template - std::enable_if_t::value, int> Invoke(void(P::*func)(Args...) const) - { - Apply(m_object, func, m_args); - return 0; - } + template + std::enable_if_t::value, int> Invoke(void(P::*func)(Args...) const) + { + Apply(m_object, func, m_args); + return 0; + } - template - std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...) const) - { - return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); - } + template + std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...) const) + { + return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + } - private: - std::tuple>...> m_args; - LuaInstance& m_instance; - T& m_object; + private: + using ArgContainer = std::tuple>...>; + using DefArgContainer = std::tuple>...>; + + template + void ProcessArgs() + { + // No argument to process + } + + template + void ProcessArgs() + { + using CheckDefValue = typename std::integral_constant= FirstDefArg>; + LuaImplArgProcesser::Process(m_instance, m_args, m_defaultArgs); + } + + template + void ProcessArgs() + { + ProcessArgs(); + ProcessArgs(); + } + + ArgContainer m_args; + DefArgContainer m_defaultArgs; + LuaInstance& m_instance; + T& m_object; + }; }; template @@ -250,18 +379,24 @@ namespace Nz return LuaImplQueryArg(*this, index, TypeTag()); } + template + T LuaInstance::Check(int index, T defValue) + { + return LuaImplQueryArg(*this, index, defValue, TypeTag()); + } + template int LuaInstance::Push(T arg) { return LuaImplReplyVal(*this, std::move(arg), TypeTag()); } - template - void LuaInstance::PushFunction(R (*func)(Args...)) + template + void LuaInstance::PushFunction(R (*func)(Args...), DefArgs... defArgs) { - PushFunction([func](LuaInstance& instance) -> int + PushFunction([func, defArgs...](LuaInstance& instance) -> int { - LuaImplFunctionProxy handler(instance); + LuaImplFunctionProxy::Impl handler(instance); handler.ProcessArgs(); return handler.Invoke(func); From 688aed016003e8f8a3c3fadf1000c936a56dec49 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Dec 2015 15:23:43 +0100 Subject: [PATCH 002/229] Lua: Fix typo Former-commit-id: 59511a3b013e2aaccf1521bfff34fca1d22d1b7c --- include/Nazara/Lua/LuaInstance.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 8c0f40ac4..d44a3cab6 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -238,7 +238,7 @@ namespace Nz public: Impl(LuaInstance& instance, DefArgs... defArgs) : m_defaultArgs(std::forward(defArgs)...), - m_instance(instance), + m_instance(instance) { } From 11abcc7da49426021ab91b1c0980eeb52c08ff7a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Dec 2015 16:34:50 +0100 Subject: [PATCH 003/229] Lua/LuaInstance: Fix compilation under Clang/GCC A big thank to gbdivers on this one Former-commit-id: f96a61ef101b7c9512ada719c82b0836aed3738b --- include/Nazara/Lua/LuaClass.inl | 6 +++--- include/Nazara/Lua/LuaInstance.inl | 16 +++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index b49dd5dcc..7d5f179c7 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -174,7 +174,7 @@ namespace Nz { m_methods[name] = method; } - + template template std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) @@ -194,7 +194,7 @@ namespace Nz { SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int { - LuaImplMethodProxy::Impl handler(instance, object, defArgs...); + typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); handler.ProcessArgs(); return handler.Invoke(func); @@ -225,7 +225,7 @@ namespace Nz { SetStaticMethod(name, [func, defArgs...] (LuaInstance& instance) -> int { - LuaImplFunctionProxy::Impl handler(instance); + typename LuaImplFunctionProxy::template Impl handler(instance); handler.ProcessArgs(); return handler.Invoke(func); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index d44a3cab6..1fa6343c7 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -196,21 +196,21 @@ namespace Nz return retVal; } - template + template struct LuaImplArgProcesser; template<> - struct LuaImplArgProcesser + struct LuaImplArgProcesser { template static void Process(LuaInstance& instance, ArgContainer& args, DefArgContainer& defArgs) { - std::get(args) = std::move(LuaImplQueryArg(instance, N + 1, std::get(defArgs), TypeTag())); + std::get(args) = std::move(LuaImplQueryArg(instance, N + 1, std::get() - N + FirstDefArg - 1>(defArgs), TypeTag())); } }; template<> - struct LuaImplArgProcesser + struct LuaImplArgProcesser { template static void Process(LuaInstance& instance, ArgContainer& args, DefArgContainer& defArgs) @@ -272,8 +272,7 @@ namespace Nz template void ProcessArgs() { - using CheckDefValue = typename std::integral_constant= FirstDefArg>; - LuaImplArgProcesser::Process(m_instance, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, m_args, m_defaultArgs); } template @@ -355,8 +354,7 @@ namespace Nz template void ProcessArgs() { - using CheckDefValue = typename std::integral_constant= FirstDefArg>; - LuaImplArgProcesser::Process(m_instance, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, m_args, m_defaultArgs); } template @@ -396,7 +394,7 @@ namespace Nz { PushFunction([func, defArgs...](LuaInstance& instance) -> int { - LuaImplFunctionProxy::Impl handler(instance); + typename LuaImplFunctionProxy::template Impl handler(instance, defArgs...); handler.ProcessArgs(); return handler.Invoke(func); From 91f778dd8980f35db1e03c550cb399794d87c877 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 10 Dec 2015 14:08:09 +0100 Subject: [PATCH 004/229] Graphics/SkyboxBackground: Add movement scaler Former-commit-id: 02682210b2b3d4b0cf27c6dd8cf171a025a92701 --- include/Nazara/Graphics/SkyboxBackground.hpp | 8 ++++++- include/Nazara/Graphics/SkyboxBackground.inl | 24 ++++++++++++++++++++ src/Nazara/Graphics/SkyboxBackground.cpp | 23 ++++++++++++++++--- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Graphics/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index b861dbbb8..427548dc0 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -32,11 +32,15 @@ namespace Nz void Draw(const AbstractViewer* viewer) const; - BackgroundType GetBackgroundType() const; + BackgroundType GetBackgroundType() const override; + inline const Vector3f& GetMovementOffset() const; + inline float GetMovementScale() const; inline const TextureRef& GetTexture() const; inline TextureSampler& GetTextureSampler(); inline const TextureSampler& GetTextureSampler() const; + inline void SetMovementOffset(const Vector3f& offset); + inline void SetMovementScale(float scale); inline void SetTexture(TextureRef cubemapTexture); inline void SetTextureSampler(const TextureSampler& sampler); @@ -48,6 +52,8 @@ namespace Nz TextureRef m_texture; TextureSampler m_sampler; + Vector3f m_movementOffset; + float m_movementScale; }; } diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl index 51b3bf123..8edb694c9 100644 --- a/include/Nazara/Graphics/SkyboxBackground.inl +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -7,6 +7,16 @@ namespace Nz { + inline const Vector3f& Nz::SkyboxBackground::GetMovementOffset() const + { + return m_movementOffset; + } + + inline float SkyboxBackground::GetMovementScale() const + { + return m_movementScale; + } + inline const TextureRef& SkyboxBackground::GetTexture() const { return m_texture; @@ -22,6 +32,20 @@ namespace Nz return m_sampler; } + inline void SkyboxBackground::SetMovementOffset(const Vector3f& offset) + { + NazaraAssert(std::isfinite(offset.x) && std::isfinite(offset.y) && std::isfinite(offset.z), "Offset must be a finite vector"); + + m_movementOffset = offset; + } + + inline void SkyboxBackground::SetMovementScale(float scale) + { + NazaraAssert(std::isfinite(scale), "Scale must be a finite value"); + + m_movementScale = scale; + } + inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture) { NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture"); diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index 1e8678c20..a70a9dd2d 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -22,9 +22,11 @@ namespace Nz static VertexBufferRef s_vertexBuffer; } - SkyboxBackground::SkyboxBackground(TextureRef cubemapTexture) + SkyboxBackground::SkyboxBackground(TextureRef cubemapTexture) : + m_movementOffset(Vector3f::Zero()), + m_movementScale(0.f) { - m_sampler.SetWrapMode(SamplerWrap_Clamp); // Nécessaire pour ne pas voir les côtés + m_sampler.SetWrapMode(SamplerWrap_Clamp); // We don't want to see any beam SetTexture(std::move(cubemapTexture)); } @@ -34,9 +36,24 @@ namespace Nz Matrix4f skyboxMatrix(viewer->GetViewMatrix()); skyboxMatrix.SetTranslation(Vector3f::Zero()); + float zNear = viewer->GetZNear(); + + constexpr float movementLimit = 0.05f; + + Vector3f offset = (viewer->GetEyePosition() - m_movementOffset) * -m_movementScale; + offset.x = Clamp(offset.x, -movementLimit, movementLimit); + offset.y = Clamp(offset.y, -movementLimit, movementLimit); + offset.z = Clamp(offset.z, -movementLimit, movementLimit); + offset *= zNear; + + Matrix4f world; + world.MakeIdentity(); + world.SetScale(Vector3f(zNear)); + world.SetTranslation(offset); + Renderer::SetIndexBuffer(s_indexBuffer); Renderer::SetMatrix(MatrixType_View, skyboxMatrix); - Renderer::SetMatrix(MatrixType_World, Matrix4f::Scale(Vector3f(viewer->GetZNear()))); + Renderer::SetMatrix(MatrixType_World, world); Renderer::SetRenderStates(s_renderStates); Renderer::SetShader(s_shader); Renderer::SetTexture(0, m_texture); From 4a71fb2922d3b3bb0244368ccf7c6e9bfb9d4a58 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 10 Dec 2015 14:09:13 +0100 Subject: [PATCH 005/229] Lua/LuaClass: Fix parameters sent to Getter/Setter Former-commit-id: 7ca17fab640f8fb0c5836f8c1ae6186873d645f2 --- include/Nazara/Lua/LuaClass.inl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 7d5f179c7..afe89c702 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -271,6 +271,7 @@ namespace Nz FinalizerFunc finalizer = info->finalizer; T* instance = *static_cast(lua.CheckUserdata(1, info->name)); + lua.Remove(1); //< Remove the instance from the Lua stack if (!finalizer || finalizer(lua, *instance)) delete instance; @@ -301,6 +302,7 @@ namespace Nz ClassIndexFunc getter = info->getter; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + lua.Remove(1); //< Remove the instance from the Lua stack if (!getter(lua, instance)) { @@ -323,8 +325,7 @@ namespace Nz ClassFunc method = info->methods[index]; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); - - lua.Remove(1); // On enlève l'argument "userdata" du stack + lua.Remove(1); //< Remove the instance from the Lua stack return method(lua, instance); } @@ -338,13 +339,14 @@ namespace Nz ClassIndexFunc setter = info->setter; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + lua.Remove(1); //< Remove the instance from the Lua stack if (!setter(lua, instance)) { std::size_t length; const char* str = lua.ToString(2, &length); - lua.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + ')'); + lua.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + "\")"); } return 1; From 8adc0097df3ee87cf993b63a9334cf507945007d Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 10 Dec 2015 23:50:09 +0100 Subject: [PATCH 006/229] Sdk/Entity: Add enable/disable mechanism Former-commit-id: 09884bdacf2b573bef516936d2580942cc5d4f66 --- SDK/include/NDK/Entity.hpp | 4 ++++ SDK/include/NDK/Entity.inl | 14 ++++++++++++++ SDK/src/NDK/Entity.cpp | 1 + SDK/src/NDK/World.cpp | 1 + 4 files changed, 20 insertions(+) diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index f2febee51..c7ab78bf5 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -34,6 +34,8 @@ namespace Ndk EntityHandle CreateHandle(); + inline void Enable(bool enable); + inline BaseComponent& GetComponent(ComponentIndex index); template ComponentType& GetComponent(); inline const Nz::Bitset<>& GetComponentBits() const; @@ -47,6 +49,7 @@ namespace Ndk void Kill(); void Invalidate(); + inline bool IsEnabled() const; inline bool IsValid() const; void RemoveAllComponents(); @@ -73,6 +76,7 @@ namespace Ndk Nz::Bitset<> m_systemBits; EntityId m_id; World* m_world; + bool m_enabled; bool m_valid; }; } diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index d30f58530..f185a4b0d 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -19,6 +19,15 @@ namespace Ndk return static_cast(AddComponent(std::move(ptr))); } + inline void Entity::Enable(bool enable) + { + if (m_enabled != enable) + { + m_enabled = enable; + Invalidate(); + } + } + inline BaseComponent& Entity::GetComponent(ComponentIndex index) { ///DOC: Le component doit être présent @@ -74,6 +83,11 @@ namespace Ndk return HasComponent(index); } + inline bool Entity::IsEnabled() const + { + return m_enabled; + } + inline bool Entity::IsValid() const { return m_valid; diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 42ecf36b1..4c0ebfb12 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -114,6 +114,7 @@ namespace Ndk void Entity::Create() { + m_enabled = true; m_valid = true; } diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 7ee1fde49..8d318ace2 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -141,6 +141,7 @@ namespace Ndk // Doit-elle en faire partie ? if (system->Filters(entity)) + if (entity->IsEnabled() && system->Filters(entity)) { // L'entité doit faire partie du système, revalidons-là (événement système) ou ajoutons-la au système if (!partOfSystem) From f8f3dbd696ea4ac23bacfe133aaea316af3cd554 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 10 Dec 2015 23:50:35 +0100 Subject: [PATCH 007/229] Sdk/World: Refactor Former-commit-id: abdef9b717866de6ab91624242583830573d9320 --- SDK/src/NDK/World.cpp | 49 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 8d318ace2..92b3fa654 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -127,34 +127,33 @@ namespace Ndk Entity* entity = &m_entities[i].entity; - // Aucun intérêt de traiter une entité n'existant plus - if (entity->IsValid()) + // Check entity validity (as it could have been reported as dirty and killed during the same iteration) + if (!entity->IsValid()) + continue; + + for (auto& system : m_systems) { - for (auto& system : m_systems) + // Ignore non-existent systems + if (!system) + continue; + + // Is our entity already part of this system? + bool partOfSystem = system->HasEntity(entity); + + // Should it be part of it? + if (entity->IsEnabled() && system->Filters(entity)) { - // Ignore non-existent systems - if (!system) - continue; + // Yes it should, add it to the system if not already done and validate it (again) + if (!partOfSystem) + system->AddEntity(entity); - // L'entité est-elle enregistrée comme faisant partie du système ? - bool partOfSystem = system->HasEntity(entity); - - // Doit-elle en faire partie ? - if (system->Filters(entity)) - if (entity->IsEnabled() && system->Filters(entity)) - { - // L'entité doit faire partie du système, revalidons-là (événement système) ou ajoutons-la au système - if (!partOfSystem) - system->AddEntity(entity); - - system->ValidateEntity(entity, !partOfSystem); - } - else - { - // Elle ne doit pas en faire partie, si elle en faisait partie nous devons la retirer - if (partOfSystem) - system->RemoveEntity(entity); - } + system->ValidateEntity(entity, !partOfSystem); + } + else + { + // No, it shouldn't, remove it if it's part of the system + if (partOfSystem) + system->RemoveEntity(entity); } } } From bfabf0cd5eb57efbb79f1770bfdeb55713c9b858 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 10 Dec 2015 23:51:19 +0100 Subject: [PATCH 008/229] Lua/LuaInstance: Add support for multi-arg conversion Allows to convert 3 numbers to a single Vector3 argument (Yup, I'm working on it) Former-commit-id: 56766e8b3821c7c4aa44036306c6bcbe658554bb --- include/Nazara/Lua/LuaInstance.hpp | 4 +- include/Nazara/Lua/LuaInstance.inl | 84 ++++++++++++++++-------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index cdf728c62..b194bf11f 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -42,8 +42,8 @@ namespace Nz bool Call(unsigned int argCount); bool Call(unsigned int argCount, unsigned int resultCount); - template T Check(int index); - template T Check(int index, T defValue); + template T Check(unsigned int* index); + template T Check(unsigned int* index, T defValue); void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 1fa6343c7..20f568f64 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -9,124 +9,124 @@ namespace Nz { // Functions args - inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { - return instance.CheckBoolean(index); + return instance.CheckBoolean((*index)++); } - inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int index, bool defValue, TypeTag) + inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int* index, bool defValue, TypeTag) { - return instance.CheckBoolean(index, defValue); + return instance.CheckBoolean((*index)++, defValue); } - inline double LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + inline double LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { - return instance.CheckNumber(index); + return instance.CheckNumber((*index)++); } - inline double LuaImplQueryArg(LuaInstance& instance, unsigned int index, double defValue, TypeTag) + inline double LuaImplQueryArg(LuaInstance& instance, unsigned int* index, double defValue, TypeTag) { - return instance.CheckNumber(index, defValue); + return instance.CheckNumber((*index)++, defValue); } - inline float LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + inline float LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { - return static_cast(instance.CheckNumber(index)); + return static_cast(instance.CheckNumber((*index)++)); } - inline float LuaImplQueryArg(LuaInstance& instance, unsigned int index, float defValue, TypeTag) + inline float LuaImplQueryArg(LuaInstance& instance, unsigned int* index, float defValue, TypeTag) { - return static_cast(instance.CheckNumber(index, defValue)); + return static_cast(instance.CheckNumber((*index)++, defValue)); } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, T defValue, TypeTag) + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) { using UnderlyingT = std::underlying_type_t; return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); } template - std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { - return static_cast(instance.CheckInteger(index)); + return static_cast(instance.CheckInteger((*index)++)); } template - std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, T defValue, TypeTag) + std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) { - return static_cast(instance.CheckInteger(index, defValue)); + return static_cast(instance.CheckInteger((*index)++, defValue)); } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { using SignedT = std::make_signed_t; return static_cast(LuaImplQueryArg(instance, index, TypeTag())); } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, T defValue, TypeTag) + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) { using SignedT = std::make_signed_t; return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); } - inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString(index, &strLength); + const char* str = instance.CheckString((*index)++, &strLength); return std::string(str, strLength); } - inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, const std::string& defValue, TypeTag) + inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const std::string& defValue, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString(index, defValue.c_str(), &strLength); + const char* str = instance.CheckString((*index)++, defValue.c_str(), &strLength); return std::string(str, strLength); } - inline String LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + inline String LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString(index, &strLength); + const char* str = instance.CheckString((*index)++, &strLength); return String(str, strLength); } - inline String LuaImplQueryArg(LuaInstance& instance, unsigned int index, const String& defValue, TypeTag) + inline String LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const String& defValue, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString(index, defValue.GetConstBuffer(), &strLength); + const char* str = instance.CheckString((*index)++, defValue.GetConstBuffer(), &strLength); return String(str, strLength); } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) { return LuaImplQueryArg(instance, index, TypeTag()); } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int index, const T& defValue, TypeTag tag) + T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const T& defValue, TypeTag tag) { - if (instance.IsValid(index)) + if (instance.IsValid(*index)) return LuaImplQueryArg(instance, index, tag); else return defValue; } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int index, const T& defValue, TypeTag) + T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const T& defValue, TypeTag) { return LuaImplQueryArg(instance, index, defValue, TypeTag()); } @@ -203,9 +203,9 @@ namespace Nz struct LuaImplArgProcesser { template - static void Process(LuaInstance& instance, ArgContainer& args, DefArgContainer& defArgs) + static void Process(LuaInstance& instance, unsigned int* argIndex, ArgContainer& args, DefArgContainer& defArgs) { - std::get(args) = std::move(LuaImplQueryArg(instance, N + 1, std::get() - N + FirstDefArg - 1>(defArgs), TypeTag())); + std::get(args) = std::move(LuaImplQueryArg(instance, argIndex, std::get() - N + FirstDefArg - 1>(defArgs), TypeTag())); } }; @@ -213,11 +213,11 @@ namespace Nz struct LuaImplArgProcesser { template - static void Process(LuaInstance& instance, ArgContainer& args, DefArgContainer& defArgs) + static void Process(LuaInstance& instance, unsigned int* argIndex, ArgContainer& args, DefArgContainer& defArgs) { NazaraUnused(defArgs); - std::get(args) = std::move(LuaImplQueryArg(instance, N + 1, TypeTag())); + std::get(args) = std::move(LuaImplQueryArg(instance, argIndex, TypeTag())); } }; @@ -244,6 +244,7 @@ namespace Nz void ProcessArgs() { + m_index = 1; ProcessArgs<0, Args...>(); } @@ -272,7 +273,7 @@ namespace Nz template void ProcessArgs() { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, &m_index, m_args, m_defaultArgs); } template @@ -285,6 +286,7 @@ namespace Nz ArgContainer m_args; DefArgContainer m_defaultArgs; LuaInstance& m_instance; + unsigned int m_index; }; }; @@ -312,6 +314,7 @@ namespace Nz void ProcessArgs() { + m_index = 1; ProcessArgs<0, Args...>(); } @@ -354,7 +357,7 @@ namespace Nz template void ProcessArgs() { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, &m_index, m_args, m_defaultArgs); } template @@ -368,17 +371,18 @@ namespace Nz DefArgContainer m_defaultArgs; LuaInstance& m_instance; T& m_object; + unsigned int m_index; }; }; template - T LuaInstance::Check(int index) + T LuaInstance::Check(unsigned int* index) { return LuaImplQueryArg(*this, index, TypeTag()); } template - T LuaInstance::Check(int index, T defValue) + T LuaInstance::Check(unsigned int* index, T defValue) { return LuaImplQueryArg(*this, index, defValue, TypeTag()); } From ee16bee137289e06bcb954ca6b438db862b54607 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 11 Dec 2015 13:08:15 +0100 Subject: [PATCH 009/229] Sdk/EntityList: Fix entity removal Former-commit-id: bd85de75d139bd824e96449310063d6fad77f269 --- SDK/include/NDK/EntityList.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/SDK/include/NDK/EntityList.inl b/SDK/include/NDK/EntityList.inl index 57bd4a8af..94fa3472f 100644 --- a/SDK/include/NDK/EntityList.inl +++ b/SDK/include/NDK/EntityList.inl @@ -41,6 +41,7 @@ namespace Ndk std::swap(*it, m_entities.back()); m_entities.pop_back(); // On le sort du vector + m_entityBits.UnboundedSet(entity->GetId(), false); } } From bff0e2df219dbd5ee13989989cf9233c03e15502 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 11 Dec 2015 13:08:32 +0100 Subject: [PATCH 010/229] Graphics/ForwardRenderQueue: Fix error Former-commit-id: a396c373b51128c57f5d8f98291f821b0bfc0c76 --- src/Nazara/Graphics/ForwardRenderQueue.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index d9527a646..a4909e333 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -502,16 +502,17 @@ namespace Nz layers.clear(); else { - for (auto it = layers.begin(); it != layers.end(); ++it) + for (auto it = layers.begin(); it != layers.end();) { Layer& layer = it->second; if (layer.clearCount++ >= 100) - it = layers.erase(it); + layers.erase(it++); else { layer.otherDrawables.clear(); layer.transparentModels.clear(); layer.transparentModelData.clear(); + ++it; } } } From 3cdf6a9f44aec801baeda57bdc89a3f1a5d2dd90 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 11 Dec 2015 13:35:44 +0100 Subject: [PATCH 011/229] Core/String: Replace Resize argument by flags, it is now capable of handling UTF-8 sequences Former-commit-id: 472e3504de06166049fcf1b850c38e5646a2d872 --- include/Nazara/Core/String.hpp | 4 ++-- src/Nazara/Core/String.cpp | 38 ++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 405eb7a19..7cd26eaf4 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -119,8 +119,8 @@ namespace Nz void Reserve(std::size_t bufferSize); - String& Resize(std::intmax_t size, char character = ' '); - String Resized(std::intmax_t size, char character = ' ') const; + String& Resize(std::intmax_t size, UInt32 flags = None); + String Resized(std::intmax_t size, UInt32 flags = None) const; String& Reverse(); String Reversed() const; diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 4d63cd87f..4aab9a368 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -2469,7 +2469,7 @@ namespace Nz m_sharedString = std::move(newString); } - String& String::Resize(std::intmax_t size, char character) + String& String::Resize(std::intmax_t size, UInt32 flags) { if (size == 0) { @@ -2481,14 +2481,22 @@ namespace Nz size = std::max(m_sharedString->size + size, 0); std::size_t newSize = static_cast(size); + + if (flags & HandleUtf8 && newSize < m_sharedString->size) + { + std::size_t characterToRemove = m_sharedString->size - newSize; + + char* ptr = &m_sharedString->string[m_sharedString->size]; + for (std::size_t i = 0; i < characterToRemove; ++i) + utf8::prior(ptr, m_sharedString->string.get()); + + newSize = ptr - m_sharedString->string.get(); + } + if (m_sharedString->capacity >= newSize) { EnsureOwnership(); - // We've got the space required, just fill it up - if (character != '\0' && newSize > m_sharedString->size) - std::memset(&m_sharedString->string[m_sharedString->size], character, newSize - m_sharedString->size); - m_sharedString->size = newSize; m_sharedString->string[newSize] = '\0'; // Adds the EoS character } @@ -2497,16 +2505,13 @@ namespace Nz auto newString = std::make_shared(newSize); std::memcpy(newString->string.get(), m_sharedString->string.get(), m_sharedString->size); - if (character != '\0') - std::memset(&newString->string[m_sharedString->size], character, newSize - m_sharedString->size); - m_sharedString = std::move(newString); } return *this; } - String String::Resized(std::intmax_t size, char character) const + String String::Resized(std::intmax_t size, UInt32 flags) const { if (size < 0) size = m_sharedString->size + size; @@ -2518,13 +2523,20 @@ namespace Nz if (newSize == m_sharedString->size) return *this; + if (flags & HandleUtf8 && newSize < m_sharedString->size) + { + std::size_t characterToRemove = m_sharedString->size - newSize; + + char* ptr = &m_sharedString->string[m_sharedString->size - 1]; + for (std::size_t i = 0; i < characterToRemove; ++i) + utf8::prior(ptr, m_sharedString->string.get()); + + newSize = ptr - m_sharedString->string.get(); + } + auto sharedStr = std::make_shared(newSize); if (newSize > m_sharedString->size) - { std::memcpy(sharedStr->string.get(), m_sharedString->string.get(), m_sharedString->size); - if (character != '\0') - std::memset(&sharedStr->string[m_sharedString->size], character, newSize - m_sharedString->size); - } else std::memcpy(sharedStr->string.get(), m_sharedString->string.get(), newSize); From 81334ae382f897838bd05adbb67afde383674b99 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 11 Dec 2015 14:13:52 +0100 Subject: [PATCH 012/229] Lua/LuaClass: Optimizations Former-commit-id: fa8bfbab3f632e91f9aeb56214844be91c94c0f5 --- include/Nazara/Lua/LuaClass.inl | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index afe89c702..8f5a0bd21 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -54,21 +54,21 @@ namespace Nz if (m_info->getter) { - lua.PushValue(1); - lua.PushValue(-2); + lua.PushValue(1); // shared_ptr on UserData + lua.PushValue(-2); // Metatable lua.PushCFunction(GetterProxy, 2); } else // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche // Ceci n'est possible que si nous n'avons ni getter, ni parent - lua.PushValue(-1); + lua.PushValue(-1); // Metatable lua.SetField("__index"); // Getter if (m_info->setter) { - lua.PushValue(1); + lua.PushValue(1); // shared_ptr on UserData lua.PushCFunction(SetterProxy, 1); lua.SetField("__newindex"); // Setter } @@ -78,11 +78,11 @@ namespace Nz { m_info->methods.push_back(pair.second); - lua.PushValue(1); + lua.PushValue(1); // shared_ptr on UserData lua.PushInteger(m_info->methods.size() - 1); lua.PushCFunction(MethodProxy, 2); - lua.SetField(pair.first); // Méthode + lua.SetField(pair.first); // Method name } } lua.Pop(); // On pop la metatable @@ -104,21 +104,21 @@ namespace Nz if (m_info->staticGetter) { - lua.PushValue(1); - lua.PushValue(-2); + lua.PushValue(1); // shared_ptr on UserData + lua.PushValue(-2); // ClassMeta lua.PushCFunction(StaticGetterProxy, 2); } else // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche // Ceci n'est possible que si nous n'avons ni getter, ni parent - lua.PushValue(-1); + lua.PushValue(-1); // ClassMeta lua.SetField("__index"); // ClassMeta.__index = StaticGetterProxy/ClassMeta if (m_info->staticSetter) { - lua.PushValue(1); + lua.PushValue(1); // shared_ptr on UserData lua.PushCFunction(StaticSetterProxy, 1); lua.SetField("__newindex"); // ClassMeta.__newindex = StaticSetterProxy } @@ -128,7 +128,7 @@ namespace Nz { m_info->staticMethods.push_back(pair.second); - lua.PushValue(1); + lua.PushValue(1); // shared_ptr on UserData lua.PushInteger(m_info->staticMethods.size() - 1); lua.PushCFunction(StaticMethodProxy, 2); @@ -244,7 +244,7 @@ namespace Nz LuaInstance& lua = *LuaInstance::GetInstance(state); ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ConstructorFunc constructor = info->constructor; + const ConstructorFunc& constructor = info->constructor; lua.Remove(1); // On enlève l'argument "table" du stack @@ -268,7 +268,7 @@ namespace Nz LuaInstance& lua = *LuaInstance::GetInstance(state); ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - FinalizerFunc finalizer = info->finalizer; + const FinalizerFunc& finalizer = info->finalizer; T* instance = *static_cast(lua.CheckUserdata(1, info->name)); lua.Remove(1); //< Remove the instance from the Lua stack @@ -299,7 +299,7 @@ namespace Nz LuaInstance& lua = *LuaInstance::GetInstance(state); ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ClassIndexFunc getter = info->getter; + const ClassIndexFunc& getter = info->getter; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); lua.Remove(1); //< Remove the instance from the Lua stack @@ -322,7 +322,7 @@ namespace Nz ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); - ClassFunc method = info->methods[index]; + const ClassFunc& method = info->methods[index]; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); lua.Remove(1); //< Remove the instance from the Lua stack @@ -336,7 +336,7 @@ namespace Nz LuaInstance& lua = *LuaInstance::GetInstance(state); ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ClassIndexFunc setter = info->setter; + const ClassIndexFunc& setter = info->setter; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); lua.Remove(1); //< Remove the instance from the Lua stack @@ -358,7 +358,7 @@ namespace Nz LuaInstance& lua = *LuaInstance::GetInstance(state); ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - StaticIndexFunc getter = info->staticGetter; + const StaticIndexFunc& getter = info->staticGetter; if (!getter(lua)) { @@ -378,7 +378,7 @@ namespace Nz ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); - StaticFunc method = info->staticMethods[index]; + const StaticFunc& method = info->staticMethods[index]; return method(lua); } @@ -389,7 +389,7 @@ namespace Nz LuaInstance& lua = *LuaInstance::GetInstance(state); ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - StaticIndexFunc setter = info->staticSetter; + const StaticIndexFunc& setter = info->staticSetter; if (!setter(lua)) { From 83bd028e8fc06a51f4a6cf9f779107ec5806a291 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 13 Dec 2015 03:29:57 +0100 Subject: [PATCH 013/229] Lua/LuaClass: Add inheritance (first implementation) Former-commit-id: 6c7f8d7dace5c857ae71958e15cc13d6a6f9ccb2 --- include/Nazara/Lua/LuaClass.hpp | 36 ++++--- include/Nazara/Lua/LuaClass.inl | 161 ++++++++++++++++++++++---------- 2 files changed, 135 insertions(+), 62 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index fe592a4aa..16399fd3a 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -13,14 +13,16 @@ #include #include #include -//#include +#include +#include namespace Nz { - template + template class LuaClass { - //static_assert(std::is_same::value || std::is_base_of::value, "P must be a base of T"); + template + friend class LuaClass; public: using ClassFunc = std::function; @@ -32,7 +34,8 @@ namespace Nz LuaClass(const String& name); - //void Inherit(LuaClass

& parent); + template + void Inherit(LuaClass

& parent); void Register(LuaInstance& lua); @@ -44,7 +47,6 @@ namespace Nz void SetMethod(const String& name, ClassFunc method); template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); - void SetBindMode(LuaBindMode mode); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); @@ -52,20 +54,15 @@ namespace Nz void SetStaticSetter(StaticIndexFunc getter); private: - static int ConstructorProxy(lua_State* state); - static int FinalizerProxy(lua_State* state); - static int InfoDestructor(lua_State* state); - static int GetterProxy(lua_State* state); - static int MethodProxy(lua_State* state); - static int SetterProxy(lua_State* state); - static int StaticGetterProxy(lua_State* state); - static int StaticMethodProxy(lua_State* state); - static int StaticSetterProxy(lua_State* state); + using ParentFunc = std::function; + using InstanceGetter = std::function; struct ClassInfo { std::vector methods; + std::vector parentGetters; std::vector staticMethods; + std::unordered_map instanceGetters; ClassIndexFunc getter = nullptr; ClassIndexFunc setter = nullptr; ConstructorFunc constructor = nullptr; @@ -76,6 +73,17 @@ namespace Nz int globalTableRef = -1; }; + static int ConstructorProxy(lua_State* state); + static int FinalizerProxy(lua_State* state); + static int InfoDestructor(lua_State* state); + static void Get(const std::shared_ptr& info, LuaInstance& lua, T& instance); + static int GetterProxy(lua_State* state); + static int MethodProxy(lua_State* state); + static int SetterProxy(lua_State* state); + static int StaticGetterProxy(lua_State* state); + static int StaticMethodProxy(lua_State* state); + static int StaticSetterProxy(lua_State* state); + std::map m_methods; std::map m_staticMethods; std::shared_ptr m_info; diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index afe89c702..79f92c385 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -4,6 +4,7 @@ #include #include +#include #include namespace Nz @@ -23,6 +24,26 @@ namespace Nz m_info->parentInfo = parent.m_info; } */ + + template + template + inline void LuaClass::Inherit(LuaClass

& parent) + { + static_assert(!std::is_same::value || std::is_base_of::value, "P must be a base of T"); + + std::shared_ptr::ClassInfo>& parentInfo = parent.m_info; + + parentInfo->instanceGetters[m_info->name] = [info = m_info](LuaInstance& lua) -> P* + { + return *static_cast(lua.CheckUserdata(1, info->name)); + }; + + m_info->parentGetters.emplace_back([parentInfo] (LuaInstance& lua, T& instance) + { + LuaClass

::Get(parentInfo, lua, instance); + }); + } + template void LuaClass::Register(LuaInstance& lua) { @@ -48,27 +69,32 @@ namespace Nz if (!lua.NewMetatable(m_info->name)) NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance"); { - lua.PushValue(1); // On associe l'UserData avec la fonction - lua.PushCFunction(FinalizerProxy, 1); - lua.SetField("__gc"); // Finalizer + // Set the type in a __type field + lua.PushString(m_info->name); + lua.SetField("__type"); - if (m_info->getter) + // Define the Finalizer + lua.PushValue(1); + lua.PushCFunction(FinalizerProxy, 1); + lua.SetField("__gc"); + + if (m_info->getter || !m_info->parentGetters.empty()) { - lua.PushValue(1); - lua.PushValue(-2); + lua.PushValue(1); // shared_ptr on UserData + lua.PushValue(-2); // Metatable lua.PushCFunction(GetterProxy, 2); } else // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche // Ceci n'est possible que si nous n'avons ni getter, ni parent - lua.PushValue(-1); + lua.PushValue(-1); // Metatable lua.SetField("__index"); // Getter if (m_info->setter) { - lua.PushValue(1); + lua.PushValue(1); // shared_ptr on UserData lua.PushCFunction(SetterProxy, 1); lua.SetField("__newindex"); // Setter } @@ -76,14 +102,20 @@ namespace Nz m_info->methods.reserve(m_methods.size()); for (auto& pair : m_methods) { + std::size_t methodIndex = m_info->methods.size(); m_info->methods.push_back(pair.second); - lua.PushValue(1); - lua.PushInteger(m_info->methods.size() - 1); + lua.PushValue(1); // shared_ptr on UserData + lua.PushInteger(methodIndex); lua.PushCFunction(MethodProxy, 2); - lua.SetField(pair.first); // Méthode + lua.SetField(pair.first); // Method name } + + m_info->instanceGetters[m_info->name] = [info = m_info](LuaInstance& lua) + { + return *static_cast(lua.CheckUserdata(1, info->name)); + }; } lua.Pop(); // On pop la metatable @@ -104,21 +136,21 @@ namespace Nz if (m_info->staticGetter) { - lua.PushValue(1); - lua.PushValue(-2); + lua.PushValue(1); // shared_ptr on UserData + lua.PushValue(-2); // ClassMeta lua.PushCFunction(StaticGetterProxy, 2); } else // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche // Ceci n'est possible que si nous n'avons ni getter, ni parent - lua.PushValue(-1); + lua.PushValue(-1); // ClassMeta lua.SetField("__index"); // ClassMeta.__index = StaticGetterProxy/ClassMeta if (m_info->staticSetter) { - lua.PushValue(1); + lua.PushValue(1); // shared_ptr on UserData lua.PushCFunction(StaticSetterProxy, 1); lua.SetField("__newindex"); // ClassMeta.__newindex = StaticSetterProxy } @@ -126,10 +158,11 @@ namespace Nz m_info->staticMethods.reserve(m_staticMethods.size()); for (auto& pair : m_staticMethods) { + std::size_t methodIndex = m_info->staticMethods.size(); m_info->staticMethods.push_back(pair.second); - lua.PushValue(1); - lua.PushInteger(m_info->staticMethods.size() - 1); + lua.PushValue(1); // shared_ptr on UserData + lua.PushInteger(methodIndex); lua.PushCFunction(StaticMethodProxy, 2); lua.SetField(pair.first); // ClassMeta.method = StaticMethodProxy @@ -181,7 +214,7 @@ namespace Nz { SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int { - LuaImplMethodProxy::Impl handler(instance, object, defArgs...); + typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); handler.ProcessArgs(); return handler.Invoke(func); @@ -243,8 +276,8 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ConstructorFunc constructor = info->constructor; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + const ConstructorFunc& constructor = info->constructor; lua.Remove(1); // On enlève l'argument "table" du stack @@ -267,8 +300,8 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - FinalizerFunc finalizer = info->finalizer; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + const FinalizerFunc& finalizer = info->finalizer; T* instance = *static_cast(lua.CheckUserdata(1, info->name)); lua.Remove(1); //< Remove the instance from the Lua stack @@ -284,34 +317,54 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - std::shared_ptr& infoPtr = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - lua.DestroyReference(infoPtr->globalTableRef); + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + lua.DestroyReference(info->globalTableRef); using namespace std; // Obligatoire pour le destructeur - infoPtr.~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur + info.~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur return 0; } + template + void LuaClass::Get(const std::shared_ptr& info, LuaInstance& lua, T& instance) + { + const ClassIndexFunc& getter = info->getter; + + if (!getter || !getter(lua, instance)) + { + // Query from the metatable + lua.GetMetatable(info->name); //< Metatable + lua.PushValue(1); //< Field + lua.GetTable(); // Metatable[Field] + + lua.Remove(-2); // Remove Metatable + + if (!lua.IsValid(-1)) + { + for (const ParentFunc& getter : info->parentGetters) + { + lua.Pop(); //< Pop the last nil value + + getter(lua, instance); + if (lua.IsValid(-1)) + return; + } + } + } + } + template int LuaClass::GetterProxy(lua_State* state) { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ClassIndexFunc getter = info->getter; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); lua.Remove(1); //< Remove the instance from the Lua stack - if (!getter(lua, instance)) - { - // On accède alors à la table - lua.PushValue(lua.GetIndexOfUpValue(2)); - lua.PushValue(-2); - lua.GetTable(); - } - + Get(info, lua, instance); return 1; } @@ -320,14 +373,26 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); - ClassFunc method = info->methods[index]; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + + T* instance = nullptr; + if (lua.GetMetatable(1)) + { + LuaType type = lua.GetField("__type"); + if (type == LuaType_String) + { + String name = lua.ToString(-1); + auto it = info->instanceGetters.find(name); + if (it != info->instanceGetters.end()) + instance = it->second(lua); + } + } - T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); lua.Remove(1); //< Remove the instance from the Lua stack - return method(lua, instance); + unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); + const ClassFunc& method = info->methods[index]; + return method(lua, *instance); } template @@ -335,8 +400,8 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ClassIndexFunc setter = info->setter; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + const ClassIndexFunc& setter = info->setter; T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); lua.Remove(1); //< Remove the instance from the Lua stack @@ -357,8 +422,8 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - StaticIndexFunc getter = info->staticGetter; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + const StaticIndexFunc& getter = info->staticGetter; if (!getter(lua)) { @@ -376,9 +441,9 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); - StaticFunc method = info->staticMethods[index]; + const StaticFunc& method = info->staticMethods[index]; return method(lua); } @@ -388,8 +453,8 @@ namespace Nz { LuaInstance& lua = *LuaInstance::GetInstance(state); - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - StaticIndexFunc setter = info->staticSetter; + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + const StaticIndexFunc& setter = info->staticSetter; if (!setter(lua)) { From 2c79e5f4e0a05d08f7aff0e5fe809cf888c4493a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 13 Dec 2015 04:40:50 +0100 Subject: [PATCH 014/229] Lua/LuaInstance: Add PushInstance Former-commit-id: 0e65124d5920a1b5ea3c644e496ae58ddee1cd8e --- include/Nazara/Lua/LuaClass.inl | 14 +------------- include/Nazara/Lua/LuaInstance.hpp | 2 ++ include/Nazara/Lua/LuaInstance.inl | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 79f92c385..5ff49defe 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -15,15 +15,6 @@ namespace Nz { m_info->name = name; } - /* - template - void LuaClass::Inherit(LuaClass

& parent) - { - static_assert(std::is_base_of::value, "P must be a base of T"); - - m_info->parentInfo = parent.m_info; - } - */ template template @@ -288,10 +279,7 @@ namespace Nz return 0; // Normalement jamais exécuté (l'erreur provoquant une exception) } - T** ud = static_cast(lua.PushUserdata(sizeof(T*))); - *ud = instance; - lua.SetMetatable(info->name); - + lua.PushInstance(info->name.GetConstBuffer(), instance); return 1; } diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index b194bf11f..504a79254 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -117,6 +117,8 @@ namespace Nz void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); void PushFunction(LuaFunction func); template void PushFunction(R(*func)(Args...), DefArgs... defArgs); + template void PushInstance(const char* tname, T* instance); + template void PushInstance(const char* tname, Args&&... args); void PushInteger(long long value); void PushLightUserdata(void* value); void PushMetatable(const char* str); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 20f568f64..bd57b2308 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -404,4 +404,18 @@ namespace Nz return handler.Invoke(func); }); } + + template + void LuaInstance::PushInstance(const char* tname, T* instance) + { + T** userdata = static_cast(PushUserdata(sizeof(T*))); + *userdata = instance; + SetMetatable(tname); + } + + template + void LuaInstance::PushInstance(const char* tname, Args&&... args) + { + PushInstance(tname, new T(std::forward(args)...)); + } } From 4c72e277841cac57094989c74462a5634e1a0152 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 13 Dec 2015 16:35:42 +0100 Subject: [PATCH 015/229] Lua/LuaClass: Add pointer objects support Former-commit-id: b4cf6fb6674278ed341a27d2a8e432845531a333 --- include/Nazara/Core/Algorithm.hpp | 6 ++++++ include/Nazara/Core/Algorithm.inl | 5 +++++ include/Nazara/Core/ObjectRef.hpp | 4 ++++ include/Nazara/Lua/LuaClass.hpp | 15 +++++++++------ include/Nazara/Lua/LuaClass.inl | 26 ++++++++++++++++++++++++++ include/Nazara/Lua/LuaInstance.inl | 26 ++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index cbbd8af04..408eb79cf 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -25,6 +25,12 @@ namespace Nz template ByteArray ComputeHash(AbstractHash* hash, const T& v); template void HashCombine(std::size_t& seed, const T& v); + template + struct PointedType + { + using type = void; //< FIXME: I can't make SFINAE work + }; + template struct TypeTag {}; diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 7c117e626..a23fea4e1 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -79,6 +79,11 @@ namespace Nz seed = static_cast(b * kMul); } + template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + inline bool Serialize(SerializationContext& context, bool value) { if (context.currentBitPos == 8) diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 0c82b3abc..8debb7d91 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -8,6 +8,7 @@ #define NAZARA_RESOURCEREF_HPP #include +#include #include #include @@ -44,6 +45,9 @@ namespace Nz private: T* m_object; }; + + template struct PointedType> {typedef T type;}; + template struct PointedType const> {typedef T type;}; } #include diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 16399fd3a..7494dbe83 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -8,6 +8,7 @@ #define NAZARA_LUACLASS_HPP #include +#include #include #include #include @@ -47,6 +48,8 @@ namespace Nz void SetMethod(const String& name, ClassFunc method); template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); + template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); + template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); @@ -63,12 +66,12 @@ namespace Nz std::vector parentGetters; std::vector staticMethods; std::unordered_map instanceGetters; - ClassIndexFunc getter = nullptr; - ClassIndexFunc setter = nullptr; - ConstructorFunc constructor = nullptr; - FinalizerFunc finalizer = nullptr; - StaticIndexFunc staticGetter = nullptr; - StaticIndexFunc staticSetter = nullptr; + ClassIndexFunc getter; + ClassIndexFunc setter; + ConstructorFunc constructor; + FinalizerFunc finalizer; + StaticIndexFunc staticGetter; + StaticIndexFunc staticSetter; String name; int globalTableRef = -1; }; diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 5ff49defe..5ca323a79 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -225,6 +225,32 @@ namespace Nz }); } + template + template + std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) + { + SetMethod(name, [func, defArgs...](LuaInstance& instance, T& object) -> int + { + typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } + + template + template + std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs) + { + SetMethod(name, [func, defArgs...](LuaInstance& instance, T& object) -> int + { + typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } + template void LuaClass::SetSetter(ClassIndexFunc setter) { diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index bd57b2308..47712161c 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -344,6 +344,32 @@ namespace Nz return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); } + template + std::enable_if_t::type>::value, int> Invoke(void(P::*func)(Args...)) + { + Apply(*m_object, func, m_args); + return 0; + } + + template + std::enable_if_t::type>::value, int> Invoke(Ret(P::*func)(Args...)) + { + return LuaImplReplyVal(m_instance, std::move(Apply(*m_object, func, m_args)), TypeTag()); + } + + template + std::enable_if_t::type>::value, int> Invoke(void(P::*func)(Args...) const) + { + Apply(*m_object, func, m_args); + return 0; + } + + template + std::enable_if_t::type>::value, int> Invoke(Ret(P::*func)(Args...) const) + { + return LuaImplReplyVal(m_instance, std::move(Apply(*m_object, func, m_args)), TypeTag()); + } + private: using ArgContainer = std::tuple>...>; using DefArgContainer = std::tuple>...>; From cfe7c79991c69653b20f22adb80b34ded63b2f16 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 13 Dec 2015 16:36:38 +0100 Subject: [PATCH 016/229] Sdk: Add server-side module Former-commit-id: 4df27d1e44d791aad234d095af08ae3c19660fba --- SDK/src/NDK/Sdk.cpp | 76 ++++++++++++++++++------------ SDK/src/NDK/World.cpp | 14 ++++-- build/scripts/tools/ndk_server.lua | 40 ++++++++++++++++ 3 files changed, 97 insertions(+), 33 deletions(-) create mode 100644 build/scripts/tools/ndk_server.lua diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 3a45b65b3..21bfd236f 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -13,64 +13,80 @@ #include #include #include -#include #include -#include -#include -#include #include #include #include -#include #include -#include #include +#ifndef NDK_SERVER +#include +#include +#include +#include +#include +#include +#endif + namespace Ndk { bool Sdk::Initialize() { if (s_referenceCounter++ > 0) - return true; // Déjà initialisé + return true; // Already initialized try { Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true); - // Initialisation du moteur + // Initialize the engine first - // Modules clients - Nz::Audio::Initialize(); - Nz::Graphics::Initialize(); - - // Modules serveurs + // Shared modules Nz::Lua::Initialize(); Nz::Noise::Initialize(); Nz::Physics::Initialize(); Nz::Utility::Initialize(); - // Initialisation du SDK + #ifndef NDK_SERVER + // Client modules + Nz::Audio::Initialize(); + Nz::Graphics::Initialize(); + #endif - // Initialisation des composants et systèmes + // SDK Initialization + + // Components BaseComponent::Initialize(); - BaseSystem::Initialize(); - // Composants - InitializeComponent("NdkCam"); + // Shared components InitializeComponent("NdkColli"); - InitializeComponent("NdkLight"); - InitializeComponent("NdkList"); - InitializeComponent("NdkGfx"); InitializeComponent("NdkNode"); InitializeComponent("NdkPhys"); InitializeComponent("NdkVeloc"); - // Systèmes - InitializeSystem(); + #ifndef NDK_SERVER + // Client components + InitializeComponent("NdkCam"); + InitializeComponent("NdkLight"); + InitializeComponent("NdkList"); + InitializeComponent("NdkGfx"); + #endif + + // Systems + + BaseSystem::Initialize(); + + // Shared systems InitializeSystem(); - InitializeSystem(); InitializeSystem(); + #ifndef NDK_SERVER + // Client systems + InitializeSystem(); + InitializeSystem(); + #endif + NazaraNotice("Initialized: SDK"); return true; } @@ -86,23 +102,25 @@ namespace Ndk { if (s_referenceCounter != 1) { - // Le module est soit encore utilisé, soit pas initialisé + // Either the module is not initialized, either it was initialized multiple times if (s_referenceCounter > 1) s_referenceCounter--; return; } - // Libération du SDK + // Uninitialize the SDK s_referenceCounter = 0; - // Libération du moteur + // Uninitialize the engine - // Modules clients + #ifndef NDK_SERVER + // Client modules Nz::Audio::Uninitialize(); Nz::Graphics::Uninitialize(); + #endif - // Modules serveurs + // Shared modules Nz::Lua::Uninitialize(); Nz::Noise::Uninitialize(); Nz::Physics::Uninitialize(); diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 92b3fa654..e8fff42f2 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -4,11 +4,14 @@ #include #include -#include #include -#include #include +#ifndef NDK_SERVER +#include +#include +#endif + namespace Ndk { World::~World() @@ -19,10 +22,13 @@ namespace Ndk void World::AddDefaultSystems() { - AddSystem(); AddSystem(); - AddSystem(); AddSystem(); + + #ifndef NDK_SERVER + AddSystem(); + AddSystem(); + #endif } const EntityHandle& World::CreateEntity() diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua new file mode 100644 index 000000000..c94170dce --- /dev/null +++ b/build/scripts/tools/ndk_server.lua @@ -0,0 +1,40 @@ +TOOL.Name = "SDKServer" + +TOOL.Directory = "../SDK/lib" +TOOL.Kind = "Library" + +TOOL.Defines = { + "NDK_BUILD", + "NDK_SERVER" +} + +TOOL.Includes = { + "../SDK/include" +} + +TOOL.Files = { + "../SDK/include/NDK/**.hpp", + "../SDK/include/NDK/**.inl", + "../SDK/src/NDK/**.hpp", + "../SDK/src/NDK/**.inl", + "../SDK/src/NDK/**.cpp" +} + +-- Exlude client-only files +TOOL.FilesExclusion = { + "../SDK/**/CameraComponent.*", + "../SDK/**/GraphicsComponent.*", + "../SDK/**/LightComponent.*", + "../SDK/**/ListenerComponent.*", + "../SDK/**/ListenerSystem.*", + "../SDK/**/RenderSystem.*", + "../SDK/**/LuaInterface_Audio.*" +} + +TOOL.Libraries = { + "NazaraCore", + "NazaraLua", + "NazaraNoise", + "NazaraPhysics", + "NazaraUtility" +} From ee2626b928fc0564675581fbae830f686d8d1c0a Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 17 Dec 2015 13:41:13 +0100 Subject: [PATCH 017/229] Lua: Optimize binding Former-commit-id: 647a1731f75098b4a8b8f8785e683533931e085a --- include/Nazara/Lua/LuaClass.hpp | 10 +- include/Nazara/Lua/LuaClass.inl | 65 ++++--- include/Nazara/Lua/LuaInstance.hpp | 2 +- include/Nazara/Lua/LuaInstance.inl | 300 +++++++++++++++-------------- 4 files changed, 198 insertions(+), 179 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 7494dbe83..b4aa9d87b 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -46,14 +46,14 @@ namespace Nz void SetFinalizer(FinalizerFunc finalizer); void SetGetter(ClassIndexFunc getter); void SetMethod(const String& name, ClassFunc method); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); - template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); - template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); + template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); + template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); - template void SetStaticMethod(const String& name, R(*func)(Args...), DefArgs... defArgs); + template void SetStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs); void SetStaticSetter(StaticIndexFunc getter); private: diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 5ca323a79..ea86b6f1a 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -201,53 +201,57 @@ namespace Nz template template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } template template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs) + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } template template - std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) + std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...](LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } template template - std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs) + std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...](LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } @@ -271,14 +275,15 @@ namespace Nz template template - void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...), DefArgs... defArgs) + void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs) { - SetStaticMethod(name, [func, defArgs...] (LuaInstance& instance) -> int - { - typename LuaImplFunctionProxy::template Impl handler(instance); - handler.ProcessArgs(); + typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetStaticMethod(name, [func, handler] (LuaInstance& lua) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, func); }); } diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 504a79254..9dbb72edf 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -116,7 +116,7 @@ namespace Nz void PushBoolean(bool value); void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); void PushFunction(LuaFunction func); - template void PushFunction(R(*func)(Args...), DefArgs... defArgs); + template void PushFunction(R(*func)(Args...), DefArgs&&... defArgs); template void PushInstance(const char* tname, T* instance); template void PushInstance(const char* tname, Args&&... args); void PushInteger(long long value); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 47712161c..9034e2cc8 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -9,126 +9,121 @@ namespace Nz { // Functions args - inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, bool* arg, TypeTag) { - return instance.CheckBoolean((*index)++); + *arg = instance.CheckBoolean(index); + return 1; } - inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int* index, bool defValue, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, bool* arg, bool defValue, TypeTag) { - return instance.CheckBoolean((*index)++, defValue); - } - - inline double LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - return instance.CheckNumber((*index)++); - } - - inline double LuaImplQueryArg(LuaInstance& instance, unsigned int* index, double defValue, TypeTag) - { - return instance.CheckNumber((*index)++, defValue); - } - - inline float LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - return static_cast(instance.CheckNumber((*index)++)); - } - - inline float LuaImplQueryArg(LuaInstance& instance, unsigned int* index, float defValue, TypeTag) - { - return static_cast(instance.CheckNumber((*index)++, defValue)); + *arg = instance.CheckBoolean(index, defValue); + return 1; } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); - } - - template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { using UnderlyingT = std::underlying_type_t; - return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); + *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag())); + + return 1; } template - std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { - return static_cast(instance.CheckInteger((*index)++)); + using UnderlyingT = std::underlying_type_t; + *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag())); + + return 1; } template - std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { - return static_cast(instance.CheckInteger((*index)++, defValue)); + *arg = static_cast(instance.CheckNumber(index)); + return 1; } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = static_cast(instance.CheckNumber(index, static_cast(defValue))); + return 1; + } + + template + std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) + { + *arg = static_cast(instance.CheckInteger(index)); + return 1; + } + + template + std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = static_cast(instance.CheckInteger(index, defValue)); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { using SignedT = std::make_signed_t; - return static_cast(LuaImplQueryArg(instance, index, TypeTag())); + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { using SignedT = std::make_signed_t; - return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); + + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); } - inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, std::string* arg, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, &strLength); + const char* str = instance.CheckString(index, &strLength); - return std::string(str, strLength); + arg->assign(str, strLength); + + return 1; } - inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const std::string& defValue, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, String* arg, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, defValue.c_str(), &strLength); + const char* str = instance.CheckString(index, &strLength); - return std::string(str, strLength); - } + arg->Set(str, strLength); - inline String LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, &strLength); - - return String(str, strLength); - } - - inline String LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const String& defValue, TypeTag) - { - std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, defValue.GetConstBuffer(), &strLength); - - return String(str, strLength); + return 1; } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { - return LuaImplQueryArg(instance, index, TypeTag()); - } - - template - T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const T& defValue, TypeTag tag) - { - if (instance.IsValid(*index)) - return LuaImplQueryArg(instance, index, tag); + if (instance.IsValid(index)) + return LuaImplQueryArg(instance, index, arg, tag); else - return defValue; + { + *arg = defValue; + return 1; + } } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const T& defValue, TypeTag) + unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { - return LuaImplQueryArg(instance, index, defValue, TypeTag()); + return LuaImplQueryArg(instance, index, arg, TypeTag()); + } + + template + unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag) + { + return LuaImplQueryArg(instance, index, arg, defValue, TypeTag()); } // Function returns @@ -203,9 +198,9 @@ namespace Nz struct LuaImplArgProcesser { template - static void Process(LuaInstance& instance, unsigned int* argIndex, ArgContainer& args, DefArgContainer& defArgs) + static unsigned int Process(LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) { - std::get(args) = std::move(LuaImplQueryArg(instance, argIndex, std::get() - N + FirstDefArg - 1>(defArgs), TypeTag())); + return LuaImplQueryArg(instance, argIndex, &std::get(args), std::get() - N + FirstDefArg - 1>(defArgs), TypeTag()); } }; @@ -213,11 +208,11 @@ namespace Nz struct LuaImplArgProcesser { template - static void Process(LuaInstance& instance, unsigned int* argIndex, ArgContainer& args, DefArgContainer& defArgs) + static unsigned int Process(LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) { NazaraUnused(defArgs); - std::get(args) = std::move(LuaImplQueryArg(instance, argIndex, TypeTag())); + return LuaImplQueryArg(instance, argIndex, &std::get(args), TypeTag()); } }; @@ -237,27 +232,28 @@ namespace Nz public: Impl(LuaInstance& instance, DefArgs... defArgs) : - m_defaultArgs(std::forward(defArgs)...), - m_instance(instance) + m_defaultArgs(std::forward(defArgs)...) { } - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { m_index = 1; - ProcessArgs<0, Args...>(); + ProcessArgs<0, Args...>(instance); } - int Invoke(void (*func)(Args...)) + int Invoke(LuaInstance& instance, void (*func)(Args...)) const { + NazaraUnused(instance); + Apply(func, m_args); return 0; } template - int Invoke(Ret (*func)(Args...)) + int Invoke(LuaInstance& instance, Ret (*func)(Args...)) const { - return LuaImplReplyVal(m_instance, std::move(Apply(func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag()); } private: @@ -265,32 +261,33 @@ namespace Nz using DefArgContainer = std::tuple>...>; template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { + NazaraUnused(instance); + // No argument to process } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, &m_index, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, &m_index, m_args, m_defaultArgs); } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - ProcessArgs(); - ProcessArgs(); + ProcessArgs(instance); + ProcessArgs(instance); } - ArgContainer m_args; + mutable ArgContainer m_args; DefArgContainer m_defaultArgs; - LuaInstance& m_instance; - unsigned int m_index; + mutable unsigned int m_index; }; }; - template + template class LuaImplMethodProxy { public: @@ -305,69 +302,75 @@ namespace Nz static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; public: - Impl(LuaInstance& instance, T& object, DefArgs... defArgs) : - m_defaultArgs(std::forward(defArgs)...), - m_instance(instance), - m_object(object) + Impl(DefArgs... defArgs) : + m_defaultArgs(std::forward(defArgs)...) { } - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { m_index = 1; - ProcessArgs<0, Args...>(); + ProcessArgs<0, Args...>(instance); } - template - std::enable_if_t::value, int> Invoke(void(P::*func)(Args...)) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, T& object, void(P::*func)(Args...)) const { - Apply(m_object, func, m_args); + NazaraUnused(instance); + + Apply(object, func, m_args); return 0; } - template - std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...)) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { - return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag()); } - template - std::enable_if_t::value, int> Invoke(void(P::*func)(Args...) const) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const { - Apply(m_object, func, m_args); + NazaraUnused(instance); + + Apply(object, func, m_args); return 0; } - template - std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...) const) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { - return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag()); } - template - std::enable_if_t::type>::value, int> Invoke(void(P::*func)(Args...)) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, T& object, void(P::*func)(Args...)) const { - Apply(*m_object, func, m_args); + NazaraUnused(instance); + + Apply(*object, func, m_args); return 0; } - template - std::enable_if_t::type>::value, int> Invoke(Ret(P::*func)(Args...)) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { - return LuaImplReplyVal(m_instance, std::move(Apply(*m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } - template - std::enable_if_t::type>::value, int> Invoke(void(P::*func)(Args...) const) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const { - Apply(*m_object, func, m_args); + NazaraUnused(instance); + + Apply(*object, func, m_args); return 0; } - template - std::enable_if_t::type>::value, int> Invoke(Ret(P::*func)(Args...) const) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { - return LuaImplReplyVal(m_instance, std::move(Apply(*m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } private: @@ -375,44 +378,54 @@ namespace Nz using DefArgContainer = std::tuple>...>; template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { + NazaraUnused(instance); + // No argument to process } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, &m_index, m_args, m_defaultArgs); + m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - ProcessArgs(); - ProcessArgs(); + ProcessArgs(instance); + ProcessArgs(instance); } - ArgContainer m_args; + mutable ArgContainer m_args; DefArgContainer m_defaultArgs; - LuaInstance& m_instance; - T& m_object; - unsigned int m_index; + mutable unsigned int m_index; }; }; template T LuaInstance::Check(unsigned int* index) { - return LuaImplQueryArg(*this, index, TypeTag()); + NazaraAssert(index, "Invalid index pointer"); + + T object; + *index += LuaImplQueryArg(*this, index, &object, TypeTag()); + + return object; } template T LuaInstance::Check(unsigned int* index, T defValue) { - return LuaImplQueryArg(*this, index, defValue, TypeTag()); - } + NazaraAssert(index, "Invalid index pointer"); + T object; + *index += LuaImplQueryArg(*this, index, &object, defValue, TypeTag()); + + return object; + } + template int LuaInstance::Push(T arg) { @@ -420,14 +433,15 @@ namespace Nz } template - void LuaInstance::PushFunction(R (*func)(Args...), DefArgs... defArgs) + void LuaInstance::PushFunction(R (*func)(Args...), DefArgs&&... defArgs) { - PushFunction([func, defArgs...](LuaInstance& instance) -> int - { - typename LuaImplFunctionProxy::template Impl handler(instance, defArgs...); - handler.ProcessArgs(); + typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + PushFunction([func, handler](LuaInstance& lua) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, func); }); } From 52599132a7a82cee0a4e38397a651d60a5fb669b Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 17 Dec 2015 13:47:25 +0100 Subject: [PATCH 018/229] Lua/LuaInstance: Add [Check|Set][Field|Global] helpers Former-commit-id: 4c6cb6097a28daa9099b3f00c201e49ec850c320 --- include/Nazara/Lua/LuaInstance.hpp | 16 ++++- include/Nazara/Lua/LuaInstance.inl | 110 +++++++++++++++++++++++++++-- src/Nazara/Lua/LuaInstance.cpp | 8 +-- 3 files changed, 122 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 9dbb72edf..f9133ec73 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -47,8 +47,16 @@ namespace Nz void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; + template T CheckField(const char* fieldName, int tableIndex = -1); + template T CheckField(const String& fieldName, int tableIndex = -1); + template T CheckField(const char* fieldName, T defValue, int tableIndex = -1); + template T CheckField(const String& fieldName, T defValue, int tableIndex = -1); long long CheckInteger(int index) const; long long CheckInteger(int index, long long defValue) const; + template T CheckGlobal(const char* fieldName) const; + template T CheckGlobal(const String& fieldName) const; + template T CheckGlobal(const char* fieldName, T defValue) const; + template T CheckGlobal(const String& fieldName, T defValue) const; double CheckNumber(int index) const; double CheckNumber(int index, double defValue) const; void CheckStack(int space, const char* error = nullptr) const; @@ -78,8 +86,8 @@ namespace Nz bool ExecuteFromStream(Stream& stream); int GetAbsIndex(int index) const; - LuaType GetField(const char* fieldName, int index = -1) const; - LuaType GetField(const String& fieldName, int index = -1) const; + LuaType GetField(const char* fieldName, int tableIndex = -1) const; + LuaType GetField(const String& fieldName, int tableIndex = -1) const; LuaType GetGlobal(const char* name) const; LuaType GetGlobal(const String& name) const; lua_State* GetInternalState() const; @@ -136,8 +144,12 @@ namespace Nz void Remove(int index); void Replace(int index); + template void SetField(const char* name, T&& arg, int tableIndex = -2); + template void SetField(const String& name, T&& arg, int tableIndex = -2); void SetField(const char* name, int tableIndex = -2); void SetField(const String& name, int tableIndex = -2); + template void SetGlobal(const char* name, T&& arg); + template void SetGlobal(const String& name, T&& arg); void SetGlobal(const char* name); void SetGlobal(const String& name); void SetMetatable(const char* tname); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 9034e2cc8..573cb462e 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -78,7 +78,7 @@ namespace Nz std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { using SignedT = std::make_signed_t; - + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); } @@ -242,7 +242,7 @@ namespace Nz ProcessArgs<0, Args...>(instance); } - int Invoke(LuaInstance& instance, void (*func)(Args...)) const + int Invoke(LuaInstance& instance, void(*func)(Args...)) const { NazaraUnused(instance); @@ -251,7 +251,7 @@ namespace Nz } template - int Invoke(LuaInstance& instance, Ret (*func)(Args...)) const + int Invoke(LuaInstance& instance, Ret(*func)(Args...)) const { return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag()); } @@ -425,7 +425,79 @@ namespace Nz return object; } - + + template + T LuaInstance::CheckField(const char* fieldName, int tableIndex) + { + T object; + + GetField(fieldName, tableIndex); + tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag()); + Pop(); + + return object; + } + + template + T LuaInstance::CheckField(const String& fieldName, int tableIndex) + { + return CheckField(fieldName.GetConstBuffer(), tableIndex); + } + + template + T LuaInstance::CheckField(const char* fieldName, T defValue, int tableIndex) + { + T object; + + GetField(fieldName, tableIndex); + tableIndex += LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); + Pop(); + + return object; + } + + template + T LuaInstance::CheckField(const String& fieldName, T defValue, int tableIndex) + { + return CheckField(fieldName.GetConstBuffer(), defValue, tableIndex); + } + + template + T LuaInstance::CheckGlobal(const char* fieldName) + { + T object; + + GetGlobal(fieldName); + tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag()); + Pop(); + + return object; + } + + template + T LuaInstance::CheckGlobal(const String& fieldName) + { + return CheckGlobal(fieldName.GetConstBuffer()); + } + + template + T LuaInstance::CheckGlobal(const char* fieldName, T defValue) + { + T object; + + GetGlobal(fieldName); + tableIndex += LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); + Pop(); + + return object; + } + + template + T LuaInstance::CheckGlobal(const String& fieldName, T defValue) + { + return CheckGlobal(fieldName.GetConstBuffer(), defValue); + } + template int LuaInstance::Push(T arg) { @@ -433,11 +505,11 @@ namespace Nz } template - void LuaInstance::PushFunction(R (*func)(Args...), DefArgs&&... defArgs) + void LuaInstance::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) { typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - PushFunction([func, handler](LuaInstance& lua) -> int + PushFunction([func, handler] (LuaInstance& lua) -> int { handler.ProcessArgs(lua); @@ -458,4 +530,30 @@ namespace Nz { PushInstance(tname, new T(std::forward(args)...)); } + + template + void LuaInstance::SetField(const char* name, T&& arg, int tableIndex) + { + Push(std::forward(arg)); + SetField(name, tableIndex); + } + + template + void LuaInstance::SetField(const String& name, T&& arg, int tableIndex) + { + SetField(name.GetConstBuffer(), std::forward(arg), tableIndex); + } + + template + void LuaInstance::SetGlobal(const char* name, T&& arg) + { + Push(std::forward(arg)); + SetGlobal(name); + } + + template + void LuaInstance::SetGlobal(const String& name, T&& arg) + { + SetGlobal(name.GetConstBuffer(), std::forward(arg)); + } } diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index dcaad2e26..09bb47bb4 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -443,14 +443,14 @@ namespace Nz return lua_absindex(m_state, index); } - LuaType LuaInstance::GetField(const char* fieldName, int index) const + LuaType LuaInstance::GetField(const char* fieldName, int tableIndex) const { - return FromLuaType(lua_getfield(m_state, index, fieldName)); + return FromLuaType(lua_getfield(m_state, tableIndex, fieldName)); } - LuaType LuaInstance::GetField(const String& fieldName, int index) const + LuaType LuaInstance::GetField(const String& fieldName, int tableIndex) const { - return FromLuaType(lua_getfield(m_state, index, fieldName.GetConstBuffer())); + return FromLuaType(lua_getfield(m_state, tableIndex, fieldName.GetConstBuffer())); } LuaType LuaInstance::GetGlobal(const char* name) const From 163e73f5d2d7f2c94b4324b56b4c572cbf2ae79e Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 17 Dec 2015 14:20:33 +0100 Subject: [PATCH 019/229] Lua: Some fixes Former-commit-id: 6db68a9c5e29a81fdd590bd11167841dda780af1 --- include/Nazara/Lua/LuaInstance.hpp | 78 +++++----- include/Nazara/Lua/LuaInstance.inl | 242 ++++++++++++++--------------- src/Nazara/Lua/LuaInstance.cpp | 58 +++---- 3 files changed, 189 insertions(+), 189 deletions(-) diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index f9133ec73..0cb1f809d 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -42,15 +42,15 @@ namespace Nz bool Call(unsigned int argCount); bool Call(unsigned int argCount, unsigned int resultCount); - template T Check(unsigned int* index); - template T Check(unsigned int* index, T defValue); + template T Check(int* index) const; + template T Check(int* index, T defValue) const; void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; - template T CheckField(const char* fieldName, int tableIndex = -1); - template T CheckField(const String& fieldName, int tableIndex = -1); - template T CheckField(const char* fieldName, T defValue, int tableIndex = -1); - template T CheckField(const String& fieldName, T defValue, int tableIndex = -1); + template T CheckField(const char* fieldName, int tableIndex = -1) const; + template T CheckField(const String& fieldName, int tableIndex = -1) const; + template T CheckField(const char* fieldName, T defValue, int tableIndex = -1) const; + template T CheckField(const String& fieldName, T defValue, int tableIndex = -1) const; long long CheckInteger(int index) const; long long CheckInteger(int index, long long defValue) const; template T CheckGlobal(const char* fieldName) const; @@ -68,17 +68,17 @@ namespace Nz void* CheckUserdata(int index, const String& tname) const; bool Compare(int index1, int index2, LuaComparison comparison) const; - void Compute(LuaOperation operation); + void Compute(LuaOperation operation) const; - void Concatenate(int count); + void Concatenate(int count) const; int CreateReference(); void DestroyReference(int ref); String DumpStack() const; - void Error(const char* message); - void Error(const String& message); + void Error(const char* message) const; + void Error(const String& message) const; bool Execute(const String& code); bool ExecuteFromFile(const String& filePath); @@ -103,7 +103,7 @@ namespace Nz LuaType GetType(int index) const; const char* GetTypeName(LuaType type) const; - void Insert(int index); + void Insert(int index) const; bool IsOfType(int index, LuaType type) const; bool IsOfType(int index, const char* tname) const; @@ -112,37 +112,37 @@ namespace Nz long long Length(int index) const; - void MoveTo(LuaInstance* instance, int n); + void MoveTo(LuaInstance* instance, int n) const; bool NewMetatable(const char* str); bool NewMetatable(const String& str); - bool Next(int index = -2); + bool Next(int index = -2) const; - void Pop(unsigned int n = 1U); + void Pop(unsigned int n = 1U) const; - template int Push(T arg); - void PushBoolean(bool value); - void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); - void PushFunction(LuaFunction func); - template void PushFunction(R(*func)(Args...), DefArgs&&... defArgs); - template void PushInstance(const char* tname, T* instance); - template void PushInstance(const char* tname, Args&&... args); - void PushInteger(long long value); - void PushLightUserdata(void* value); - void PushMetatable(const char* str); - void PushMetatable(const String& str); - void PushNil(); - void PushNumber(double value); - void PushReference(int ref); - void PushString(const char* str); - void PushString(const char* str, unsigned int size); - void PushString(const String& str); - void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0); - void* PushUserdata(unsigned int size); - void PushValue(int index); + template int Push(T arg) const; + void PushBoolean(bool value) const; + void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0) const; + void PushFunction(LuaFunction func) const; + template void PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const; + template void PushInstance(const char* tname, T* instance) const; + template void PushInstance(const char* tname, Args&&... args) const; + void PushInteger(long long value) const; + void PushLightUserdata(void* value) const; + void PushMetatable(const char* str) const; + void PushMetatable(const String& str) const; + void PushNil() const; + void PushNumber(double value) const; + void PushReference(int ref) const; + void PushString(const char* str) const; + void PushString(const char* str, unsigned int size) const; + void PushString(const String& str) const; + void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0) const; + void* PushUserdata(unsigned int size) const; + void PushValue(int index) const; - void Remove(int index); - void Replace(int index); + void Remove(int index) const; + void Replace(int index) const; template void SetField(const char* name, T&& arg, int tableIndex = -2); template void SetField(const String& name, T&& arg, int tableIndex = -2); @@ -152,9 +152,9 @@ namespace Nz template void SetGlobal(const String& name, T&& arg); void SetGlobal(const char* name); void SetGlobal(const String& name); - void SetMetatable(const char* tname); - void SetMetatable(const String& tname); - void SetMetatable(int index); + void SetMetatable(const char* tname) const; + void SetMetatable(const String& tname) const; + void SetMetatable(int index) const; void SetMemoryLimit(UInt32 memoryLimit); void SetTable(int index = -3); void SetTimeLimit(UInt32 timeLimit); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 573cb462e..c0ff1bc85 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -9,80 +9,19 @@ namespace Nz { // Functions args - inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, bool* arg, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, bool* arg, TypeTag) { *arg = instance.CheckBoolean(index); return 1; } - inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, bool* arg, bool defValue, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, bool* arg, bool defValue, TypeTag) { *arg = instance.CheckBoolean(index, defValue); return 1; } - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) - { - using UnderlyingT = std::underlying_type_t; - *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag())); - - return 1; - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - using UnderlyingT = std::underlying_type_t; - *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag())); - - return 1; - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) - { - *arg = static_cast(instance.CheckNumber(index)); - return 1; - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - *arg = static_cast(instance.CheckNumber(index, static_cast(defValue))); - return 1; - } - - template - std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) - { - *arg = static_cast(instance.CheckInteger(index)); - return 1; - } - - template - std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - *arg = static_cast(instance.CheckInteger(index, defValue)); - return 1; - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) - { - using SignedT = std::make_signed_t; - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - using SignedT = std::make_signed_t; - - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); - } - - inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, std::string* arg, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, std::string* arg, TypeTag) { std::size_t strLength = 0; const char* str = instance.CheckString(index, &strLength); @@ -92,7 +31,7 @@ namespace Nz return 1; } - inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, String* arg, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, String* arg, TypeTag) { std::size_t strLength = 0; const char* str = instance.CheckString(index, &strLength); @@ -103,7 +42,68 @@ namespace Nz } template - unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag())); + + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag())); + + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) + { + *arg = static_cast(instance.CheckNumber(index)); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = static_cast(instance.CheckNumber(index, static_cast(defValue))); + return 1; + } + + template + std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) + { + *arg = static_cast(instance.CheckInteger(index)); + return 1; + } + + template + std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = static_cast(instance.CheckInteger(index, defValue)); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) + { + using SignedT = std::make_signed_t; + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + using SignedT = std::make_signed_t; + + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); + } + + template + unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { if (instance.IsValid(index)) return LuaImplQueryArg(instance, index, arg, tag); @@ -115,38 +115,38 @@ namespace Nz } template - unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) + unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) { return LuaImplQueryArg(instance, index, arg, TypeTag()); } template - unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag) + unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag) { return LuaImplQueryArg(instance, index, arg, defValue, TypeTag()); } // Function returns - inline int LuaImplReplyVal(LuaInstance& instance, bool val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, bool val, TypeTag) { instance.PushBoolean(val); return 1; } - inline int LuaImplReplyVal(LuaInstance& instance, double val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, double val, TypeTag) { instance.PushNumber(val); return 1; } - inline int LuaImplReplyVal(LuaInstance& instance, float val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, float val, TypeTag) { instance.PushNumber(val); return 1; } template - std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + std::enable_if_t::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) { using EnumT = typename std::underlying_type::type; @@ -154,34 +154,34 @@ namespace Nz } template - std::enable_if_t::value && !std::is_unsigned::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + std::enable_if_t::value && !std::is_unsigned::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) { instance.PushInteger(val); return 1; } template - std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + std::enable_if_t::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) { using SignedT = typename std::make_signed::type; return LuaImplReplyVal(instance, static_cast(val), TypeTag()); } - inline int LuaImplReplyVal(LuaInstance& instance, std::string val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, std::string val, TypeTag) { instance.PushString(val.c_str(), val.size()); return 1; } - inline int LuaImplReplyVal(LuaInstance& instance, String val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, String val, TypeTag) { instance.PushString(std::move(val)); return 1; } template - int LuaImplReplyVal(LuaInstance& instance, std::pair val, TypeTag>) + int LuaImplReplyVal(const LuaInstance& instance, std::pair val, TypeTag>) { int retVal = 0; @@ -198,7 +198,7 @@ namespace Nz struct LuaImplArgProcesser { template - static unsigned int Process(LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) + static unsigned int Process(const LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) { return LuaImplQueryArg(instance, argIndex, &std::get(args), std::get() - N + FirstDefArg - 1>(defArgs), TypeTag()); } @@ -208,7 +208,7 @@ namespace Nz struct LuaImplArgProcesser { template - static unsigned int Process(LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) + static unsigned int Process(const LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) { NazaraUnused(defArgs); @@ -231,18 +231,18 @@ namespace Nz static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; public: - Impl(LuaInstance& instance, DefArgs... defArgs) : + Impl(DefArgs... defArgs) : m_defaultArgs(std::forward(defArgs)...) { } - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { m_index = 1; ProcessArgs<0, Args...>(instance); } - int Invoke(LuaInstance& instance, void(*func)(Args...)) const + int Invoke(const LuaInstance& instance, void(*func)(Args...)) const { NazaraUnused(instance); @@ -251,7 +251,7 @@ namespace Nz } template - int Invoke(LuaInstance& instance, Ret(*func)(Args...)) const + int Invoke(const LuaInstance& instance, Ret(*func)(Args...)) const { return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag()); } @@ -261,7 +261,7 @@ namespace Nz using DefArgContainer = std::tuple>...>; template - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { NazaraUnused(instance); @@ -269,13 +269,13 @@ namespace Nz } template - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, &m_index, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); } template - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { ProcessArgs(instance); ProcessArgs(instance); @@ -307,14 +307,14 @@ namespace Nz { } - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { m_index = 1; ProcessArgs<0, Args...>(instance); } template - std::enable_if_t::value, int> Invoke(LuaInstance& instance, T& object, void(P::*func)(Args...)) const + std::enable_if_t::value, int> Invoke(const LuaInstance& instance, T& object, void(P::*func)(Args...)) const { NazaraUnused(instance); @@ -323,13 +323,13 @@ namespace Nz } template - std::enable_if_t::value, int> Invoke(LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const + std::enable_if_t::value, int> Invoke(const LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag()); } template - std::enable_if_t::value, int> Invoke(LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const + std::enable_if_t::value, int> Invoke(const LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const { NazaraUnused(instance); @@ -338,13 +338,13 @@ namespace Nz } template - std::enable_if_t::value, int> Invoke(LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const + std::enable_if_t::value, int> Invoke(const LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag()); } template - std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, T& object, void(P::*func)(Args...)) const + std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, T& object, void(P::*func)(Args...)) const { NazaraUnused(instance); @@ -353,13 +353,13 @@ namespace Nz } template - std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const + std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } template - std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const + std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const { NazaraUnused(instance); @@ -368,7 +368,7 @@ namespace Nz } template - std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const + std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } @@ -378,7 +378,7 @@ namespace Nz using DefArgContainer = std::tuple>...>; template - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { NazaraUnused(instance); @@ -386,13 +386,13 @@ namespace Nz } template - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); } template - void ProcessArgs(LuaInstance& instance) const + void ProcessArgs(const LuaInstance& instance) const { ProcessArgs(instance); ProcessArgs(instance); @@ -405,29 +405,29 @@ namespace Nz }; template - T LuaInstance::Check(unsigned int* index) + T LuaInstance::Check(int* index) const { NazaraAssert(index, "Invalid index pointer"); T object; - *index += LuaImplQueryArg(*this, index, &object, TypeTag()); + *index += LuaImplQueryArg(*this, *index, &object, TypeTag()); return object; } template - T LuaInstance::Check(unsigned int* index, T defValue) + T LuaInstance::Check(int* index, T defValue) const { NazaraAssert(index, "Invalid index pointer"); T object; - *index += LuaImplQueryArg(*this, index, &object, defValue, TypeTag()); + *index += LuaImplQueryArg(*this, *index, &object, defValue, TypeTag()); return object; } template - T LuaInstance::CheckField(const char* fieldName, int tableIndex) + T LuaInstance::CheckField(const char* fieldName, int tableIndex) const { T object; @@ -439,13 +439,13 @@ namespace Nz } template - T LuaInstance::CheckField(const String& fieldName, int tableIndex) + T LuaInstance::CheckField(const String& fieldName, int tableIndex) const { - return CheckField(fieldName.GetConstBuffer(), tableIndex); + return CheckField(fieldName.GetConstBuffer(), tableIndex); } template - T LuaInstance::CheckField(const char* fieldName, T defValue, int tableIndex) + T LuaInstance::CheckField(const char* fieldName, T defValue, int tableIndex) const { T object; @@ -457,55 +457,55 @@ namespace Nz } template - T LuaInstance::CheckField(const String& fieldName, T defValue, int tableIndex) + T LuaInstance::CheckField(const String& fieldName, T defValue, int tableIndex) const { - return CheckField(fieldName.GetConstBuffer(), defValue, tableIndex); + return CheckField(fieldName.GetConstBuffer(), defValue, tableIndex); } template - T LuaInstance::CheckGlobal(const char* fieldName) + T LuaInstance::CheckGlobal(const char* fieldName) const { T object; GetGlobal(fieldName); - tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag()); + LuaImplQueryArg(*this, -1, &object, TypeTag()); Pop(); return object; } template - T LuaInstance::CheckGlobal(const String& fieldName) + T LuaInstance::CheckGlobal(const String& fieldName) const { - return CheckGlobal(fieldName.GetConstBuffer()); + return CheckGlobal(fieldName.GetConstBuffer()); } template - T LuaInstance::CheckGlobal(const char* fieldName, T defValue) + T LuaInstance::CheckGlobal(const char* fieldName, T defValue) const { T object; GetGlobal(fieldName); - tableIndex += LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); + LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); Pop(); return object; } template - T LuaInstance::CheckGlobal(const String& fieldName, T defValue) + T LuaInstance::CheckGlobal(const String& fieldName, T defValue) const { - return CheckGlobal(fieldName.GetConstBuffer(), defValue); + return CheckGlobal(fieldName.GetConstBuffer(), defValue); } template - int LuaInstance::Push(T arg) + int LuaInstance::Push(T arg) const { return LuaImplReplyVal(*this, std::move(arg), TypeTag()); } template - void LuaInstance::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) + void LuaInstance::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const { typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); @@ -518,7 +518,7 @@ namespace Nz } template - void LuaInstance::PushInstance(const char* tname, T* instance) + void LuaInstance::PushInstance(const char* tname, T* instance) const { T** userdata = static_cast(PushUserdata(sizeof(T*))); *userdata = instance; @@ -526,7 +526,7 @@ namespace Nz } template - void LuaInstance::PushInstance(const char* tname, Args&&... args) + void LuaInstance::PushInstance(const char* tname, Args&&... args) const { PushInstance(tname, new T(std::forward(args)...)); } diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 09bb47bb4..3a1880681 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -279,7 +279,7 @@ namespace Nz return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0); } - void LuaInstance::Compute(LuaOperation operation) + void LuaInstance::Compute(LuaOperation operation) const { #ifdef NAZARA_DEBUG if (operation > LuaOperation_Max) @@ -292,7 +292,7 @@ namespace Nz lua_arith(m_state, s_operations[operation]); } - void LuaInstance::Concatenate(int count) + void LuaInstance::Concatenate(int count) const { lua_concat(m_state, count); } @@ -366,12 +366,12 @@ namespace Nz return stream.ToString(); } - void LuaInstance::Error(const char* message) + void LuaInstance::Error(const char* message) const { luaL_error(m_state, message); } - void LuaInstance::Error(const String& message) + void LuaInstance::Error(const String& message) const { luaL_error(m_state, message.GetConstBuffer()); } @@ -531,7 +531,7 @@ namespace Nz return lua_typename(m_state, s_types[type]); } - void LuaInstance::Insert(int index) + void LuaInstance::Insert(int index) const { lua_insert(m_state, index); } @@ -596,7 +596,7 @@ namespace Nz return luaL_len(m_state, index); } - void LuaInstance::MoveTo(LuaInstance* instance, int n) + void LuaInstance::MoveTo(LuaInstance* instance, int n) const { lua_xmove(m_state, instance->m_state, n); } @@ -611,27 +611,27 @@ namespace Nz return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0; } - bool LuaInstance::Next(int index) + bool LuaInstance::Next(int index) const { return lua_next(m_state, index) != 0; } - void LuaInstance::Pop(unsigned int n) + void LuaInstance::Pop(unsigned int n) const { lua_pop(m_state, static_cast(n)); } - void LuaInstance::PushBoolean(bool value) + void LuaInstance::PushBoolean(bool value) const { lua_pushboolean(m_state, (value) ? 1 : 0); } - void LuaInstance::PushCFunction(LuaCFunction func, unsigned int upvalueCount) + void LuaInstance::PushCFunction(LuaCFunction func, unsigned int upvalueCount) const { lua_pushcclosure(m_state, func, upvalueCount); } - void LuaInstance::PushFunction(LuaFunction func) + void LuaInstance::PushFunction(LuaFunction func) const { LuaFunction* luaFunc = reinterpret_cast(lua_newuserdata(m_state, sizeof(LuaFunction))); PlacementNew(luaFunc, std::move(func)); @@ -639,77 +639,77 @@ namespace Nz lua_pushcclosure(m_state, ProxyFunc, 1); } - void LuaInstance::PushInteger(long long value) + void LuaInstance::PushInteger(long long value) const { lua_pushinteger(m_state, value); } - void LuaInstance::PushLightUserdata(void* value) + void LuaInstance::PushLightUserdata(void* value) const { lua_pushlightuserdata(m_state, value); } - void LuaInstance::PushMetatable(const char* str) + void LuaInstance::PushMetatable(const char* str) const { luaL_getmetatable(m_state, str); } - void LuaInstance::PushMetatable(const String& str) + void LuaInstance::PushMetatable(const String& str) const { luaL_getmetatable(m_state, str.GetConstBuffer()); } - void LuaInstance::PushNil() + void LuaInstance::PushNil() const { lua_pushnil(m_state); } - void LuaInstance::PushNumber(double value) + void LuaInstance::PushNumber(double value) const { lua_pushnumber(m_state, value); } - void LuaInstance::PushReference(int ref) + void LuaInstance::PushReference(int ref) const { lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref); } - void LuaInstance::PushString(const char* str) + void LuaInstance::PushString(const char* str) const { lua_pushstring(m_state, str); } - void LuaInstance::PushString(const char* str, unsigned int size) + void LuaInstance::PushString(const char* str, unsigned int size) const { lua_pushlstring(m_state, str, size); } - void LuaInstance::PushString(const String& str) + void LuaInstance::PushString(const String& str) const { lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize()); } - void LuaInstance::PushTable(unsigned int sequenceElementCount, unsigned int arrayElementCount) + void LuaInstance::PushTable(unsigned int sequenceElementCount, unsigned int arrayElementCount) const { lua_createtable(m_state, sequenceElementCount, arrayElementCount); } - void* LuaInstance::PushUserdata(unsigned int size) + void* LuaInstance::PushUserdata(unsigned int size) const { return lua_newuserdata(m_state, size); } - void LuaInstance::PushValue(int index) + void LuaInstance::PushValue(int index) const { lua_pushvalue(m_state, index); } - void LuaInstance::Remove(int index) + void LuaInstance::Remove(int index) const { lua_remove(m_state, index); } - void LuaInstance::Replace(int index) + void LuaInstance::Replace(int index) const { lua_replace(m_state, index); } @@ -734,17 +734,17 @@ namespace Nz lua_setglobal(m_state, name.GetConstBuffer()); } - void LuaInstance::SetMetatable(const char* tname) + void LuaInstance::SetMetatable(const char* tname) const { luaL_setmetatable(m_state, tname); } - void LuaInstance::SetMetatable(const String& tname) + void LuaInstance::SetMetatable(const String& tname) const { luaL_setmetatable(m_state, tname.GetConstBuffer()); } - void LuaInstance::SetMetatable(int index) + void LuaInstance::SetMetatable(int index) const { lua_setmetatable(m_state, index); } From 39f2c4eb072f217634f642e51fa8beeda8e4fcfe Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 18 Dec 2015 13:26:08 +0100 Subject: [PATCH 020/229] Lua/LuaInstance: Resolve ambiguous overload Former-commit-id: 581b56a8e83f67b4f44413b7c4e75071e77cf0f5 --- include/Nazara/Lua/LuaInstance.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index c0ff1bc85..1ce27b48c 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -103,7 +103,7 @@ namespace Nz } template - unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { if (instance.IsValid(index)) return LuaImplQueryArg(instance, index, arg, tag); From 26e7fa1686abf0fd4c7955c0f82ef5bb953a9b03 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 18 Dec 2015 13:27:09 +0100 Subject: [PATCH 021/229] Ndk: Add EntityOwner class Former-commit-id: ef7486e39124642cb1d1b8c24c4c726dc592486b --- SDK/include/NDK/EntityHandle.hpp | 2 +- SDK/include/NDK/EntityHandle.inl | 2 +- SDK/include/NDK/EntityOwner.hpp | 35 ++++++++++++++ SDK/include/NDK/EntityOwner.inl | 78 ++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 SDK/include/NDK/EntityOwner.hpp create mode 100644 SDK/include/NDK/EntityOwner.inl diff --git a/SDK/include/NDK/EntityHandle.hpp b/SDK/include/NDK/EntityHandle.hpp index c6a325b7e..8a5594dbe 100644 --- a/SDK/include/NDK/EntityHandle.hpp +++ b/SDK/include/NDK/EntityHandle.hpp @@ -71,7 +71,7 @@ namespace Ndk static const EntityHandle InvalidHandle; - private: + protected: void OnEntityDestroyed(); void OnEntityMoved(Entity* newEntity); diff --git a/SDK/include/NDK/EntityHandle.inl b/SDK/include/NDK/EntityHandle.inl index 636287878..03e7ad829 100644 --- a/SDK/include/NDK/EntityHandle.inl +++ b/SDK/include/NDK/EntityHandle.inl @@ -135,7 +135,7 @@ namespace Ndk inline EntityHandle& EntityHandle::operator=(EntityHandle&& handle) { - Reset(handle); + Reset(std::move(handle)); return *this; } diff --git a/SDK/include/NDK/EntityOwner.hpp b/SDK/include/NDK/EntityOwner.hpp new file mode 100644 index 000000000..3e2b6cdab --- /dev/null +++ b/SDK/include/NDK/EntityOwner.hpp @@ -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_ENTITYOWNER_HPP +#define NDK_ENTITYOWNER_HPP + +#include + +namespace Ndk +{ + class EntityOwner : public EntityHandle + { + public: + EntityOwner() = default; + explicit EntityOwner(Entity* entity); + EntityOwner(const EntityOwner& handle); + EntityOwner(EntityOwner&& handle); + ~EntityOwner(); + + void Reset(Entity* entity = nullptr); + void Reset(const EntityOwner& handle); + void Reset(EntityOwner&& handle); + + EntityOwner& operator=(Entity* entity); + EntityOwner& operator=(const EntityOwner& handle); + EntityOwner& operator=(EntityOwner&& handle); + }; +} + +#include + +#endif // NDK_ENTITYOwner_HPP diff --git a/SDK/include/NDK/EntityOwner.inl b/SDK/include/NDK/EntityOwner.inl new file mode 100644 index 000000000..c2335268f --- /dev/null +++ b/SDK/include/NDK/EntityOwner.inl @@ -0,0 +1,78 @@ +// 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 +#include +#include + +namespace Ndk +{ + inline EntityOwner::EntityOwner(Entity* entity) : + EntityOwner() + { + Reset(entity); + } + + inline EntityOwner::EntityOwner(const EntityOwner& handle) : + EntityHandle(handle) + { + } + + inline EntityOwner::EntityOwner(EntityOwner&& handle) : + EntityHandle(std::move(handle)) + { + } + + inline EntityOwner::~EntityOwner() + { + Reset(nullptr); + } + + inline void EntityOwner::Reset(Entity* entity) + { + if (m_entity) + m_entity->Kill(); + + EntityHandle::Reset(entity); + } + + inline void EntityOwner::Reset(const EntityOwner& handle) + { + Reset(handle.GetEntity()); + } + + inline void EntityOwner::Reset(EntityOwner&& handle) + { + Reset(handle.GetEntity()); + } + + inline EntityOwner& EntityOwner::operator=(Entity* entity) + { + Reset(entity); + + return *this; + } + + inline EntityOwner& EntityOwner::operator=(const EntityOwner& handle) + { + Reset(handle); + + return *this; + } + + inline EntityOwner& EntityOwner::operator=(EntityOwner&& handle) + { + Reset(std::move(handle)); + + return *this; + } +} + +namespace std +{ + template<> + struct hash : public hash + { + }; +} From 1926b28d638564679e4a4d3adaa8118669fac403 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 18 Dec 2015 13:46:15 +0100 Subject: [PATCH 022/229] Graphics/Light: Add missing GetInnerAngleCosine() and GetInvRadius() implementation Former-commit-id: 7deb6b2dd76139ccc98801cdb36a27e1f5979722 --- include/Nazara/Graphics/Light.inl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index b6b1574a3..ad64e93dc 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -32,6 +32,16 @@ namespace Nz return m_innerAngle; } + inline float Light::GetInnerAngleCosine() const + { + return m_innerAngleCosine; + } + + inline float Light::GetInvRadius() const + { + return m_invRadius; + } + inline LightType Light::GetLightType() const { return m_type; From 94037128b369121869e7ee296695445aa27d2d11 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Dec 2015 12:02:19 +0100 Subject: [PATCH 023/229] Update Readme (#50) Former-commit-id: 3c0a0b203f2b97b6b3a05be14c279201afe1b4c0 --- readme.md | 10 +++++----- readme_fr.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/readme.md b/readme.md index 759f901e9..f697180ea 100644 --- a/readme.md +++ b/readme.md @@ -22,13 +22,13 @@ Use the premake build system in the build directory then compile the engine for How to use ---------- -You can find tutorials on installation, compilation and use on the [official wiki](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara:Tutorials) (**\*Broken link***) +You can find tutorials on installation, compilation and use on the [official wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) Contribute ---------- #####Don't hesitate to contribute to Nazara Engine by:##### -- Extending the [wiki](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara) (**\*Broken link***) +- Extending the [wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) - Submitting a patch to GitHub - Post suggestions/bugs on the forum or the [GitHub tracker](https://github.com/DigitalPulseSoftware/NazaraEngine/issues) - [Fork the project](https://github.com/DigitalPulseSoftware/NazaraEngine/fork) on GitHub and [push your changes](https://github.com/DigitalPulseSoftware/NazaraEngine/pulls) @@ -37,9 +37,9 @@ Contribute Links ----- -[Website](http://www.digitalpulsesoftware.com) -[Wiki](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara) (**\*Broken link***) -[Forum](http://forum.digitalpulsesoftware.com) +[Website](http://www.digitalpulsesoftware.net) +[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) +[Forum](http://forum.digitalpulsesoftware.net) ###Thanks to:### - **RafBill** and **Raakz:** Finding bugs and/or testing diff --git a/readme_fr.md b/readme_fr.md index fd8aaaf91..7af7b3875 100644 --- a/readme_fr.md +++ b/readme_fr.md @@ -22,13 +22,13 @@ Utilisez le système premake pour construire le projet du moteur, dans le dossie Utilisation ----------- -Vous pouvez lire des tutoriaux sur l'installation, la compilation et l'utilisation sur le [wiki officiel](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara:Tutorials) (**\*Lien brisé***) +Vous pouvez lire des tutoriaux sur l'installation, la compilation et l'utilisation sur le [wiki officiel](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) (**\*En cours de rédaction***) Contribution ---------- #####N'hésitez pas à contribuer à Nazara Engine en :##### -- Contribuant au [wiki](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara) (**\*Lien brisé***) +- Contribuant au [wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) (**\*Lien brisé***) - Soumettant un patch sur GitHub - Postant des suggestions/bugs sur le forum ou sur le [tracker GitHub](https://github.com/DigitalPulseSoftware/NazaraEngine/issues) - Faisant un [fork du projet](https://github.com/DigitalPulseSoftware/NazaraEngine/fork) sur GitHub et en [proposant vos changements](https://github.com/DigitalPulseSoftware/NazaraEngine/pulls) @@ -37,9 +37,9 @@ Contribution Liens ----- -[Website](http://www.digitalpulsesoftware.com) -[Wiki](http://wiki.digitalpulsesoftware.com/index.php?title=Nazara) (**\*Lien brisé***) -[Forum](http://forum.digitalpulsesoftware.com) +[Website](http://www.digitalpulsesoftware.net) +[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) +[Forum](http://forum.digitalpulsesoftware.net) ###Remerciements:### - **RafBill** et **Raakz:** Recherche de bugs et/ou tests From 84f6803aac91408954d14fb49356527631f4f0c1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Dec 2015 12:03:24 +0100 Subject: [PATCH 024/229] Fix Markdown I just broken Former-commit-id: 60468e60076aa6d759b4c6b7779dae1346e74cd3 --- readme.md | 2 +- readme_fr.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index f697180ea..ea7595a96 100644 --- a/readme.md +++ b/readme.md @@ -38,7 +38,7 @@ Contribute Links ----- [Website](http://www.digitalpulsesoftware.net) -[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) +[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) [Forum](http://forum.digitalpulsesoftware.net) ###Thanks to:### diff --git a/readme_fr.md b/readme_fr.md index 7af7b3875..bc3364350 100644 --- a/readme_fr.md +++ b/readme_fr.md @@ -38,7 +38,7 @@ Contribution Liens ----- [Website](http://www.digitalpulsesoftware.net) -[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) +[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) [Forum](http://forum.digitalpulsesoftware.net) ###Remerciements:### From 92eaf8db1f9d48ae299132359b10f222628d1964 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:08:30 +0100 Subject: [PATCH 025/229] Linux is case-sensitive Former-commit-id: 40f31badac6bd4f19d8b54850ab0be8e486f08c2 --- SDK/include/NDK/Algorithm.hpp | 2 +- SDK/include/NDK/Component.inl | 2 +- SDK/include/NDK/System.inl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SDK/include/NDK/Algorithm.hpp b/SDK/include/NDK/Algorithm.hpp index 61582012d..da75f4ff7 100644 --- a/SDK/include/NDK/Algorithm.hpp +++ b/SDK/include/NDK/Algorithm.hpp @@ -20,6 +20,6 @@ namespace Ndk template bool IsSystem(S& system); } -#include +#include #endif // NDK_ALGORITHM_HPP diff --git a/SDK/include/NDK/Component.inl b/SDK/include/NDK/Component.inl index b016fd8be..e39091224 100644 --- a/SDK/include/NDK/Component.inl +++ b/SDK/include/NDK/Component.inl @@ -2,7 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include +#include #include namespace Ndk diff --git a/SDK/include/NDK/System.inl b/SDK/include/NDK/System.inl index c7bfdf401..9b382d924 100644 --- a/SDK/include/NDK/System.inl +++ b/SDK/include/NDK/System.inl @@ -2,7 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include +#include #include namespace Ndk From 7f4a7c1012b0eb4bfc92c825c4d57629b70e87e3 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:15:20 +0100 Subject: [PATCH 026/229] Add override where missing Former-commit-id: 2a876a280bc29f45ba81cedff5a3efeb5b70efab --- .../NDK/Components/CameraComponent.hpp | 20 +++++++++---------- include/Nazara/Core/Hash/Whirlpool.hpp | 4 ++-- .../Nazara/Graphics/DeferredRenderQueue.hpp | 2 +- .../Nazara/Graphics/ForwardRenderQueue.hpp | 2 +- .../Graphics/GuillotineTextureAtlas.hpp | 2 +- include/Nazara/Graphics/ParticleSystem.hpp | 2 +- include/Nazara/Graphics/SkeletalModel.hpp | 2 +- include/Nazara/Physics/Geom.hpp | 2 +- include/Nazara/Renderer/RenderTexture.hpp | 4 ++-- include/Nazara/Renderer/RenderWindow.hpp | 8 ++++---- include/Nazara/Utility/SimpleTextDrawer.hpp | 2 +- src/Nazara/Audio/Formats/sndfileLoader.cpp | 2 +- 12 files changed, 26 insertions(+), 26 deletions(-) diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index 4eea340e8..f96d32da4 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -33,20 +33,20 @@ namespace Ndk inline void EnsureViewMatrixUpdate() const; inline void EnsureViewportUpdate() const; - inline float GetAspectRatio() const; - inline Nz::Vector3f GetEyePosition() const; - inline Nz::Vector3f GetForward() const; + inline float GetAspectRatio() const override; + inline Nz::Vector3f GetEyePosition() const override; + inline Nz::Vector3f GetForward() const override; inline float GetFOV() const; - inline const Nz::Frustumf& GetFrustum() const; + inline const Nz::Frustumf& GetFrustum() const override; inline unsigned int GetLayer() const; - inline const Nz::Matrix4f& GetProjectionMatrix() const; + inline const Nz::Matrix4f& GetProjectionMatrix() const override; inline Nz::ProjectionType GetProjectionType() const; - inline const Nz::RenderTarget* GetTarget() const; + inline const Nz::RenderTarget* GetTarget() const override; inline const Nz::Rectf& GetTargetRegion() const; - inline const Nz::Matrix4f& GetViewMatrix() const; - inline const Nz::Recti& GetViewport() const; - inline float GetZFar() const; - inline float GetZNear() const; + inline const Nz::Matrix4f& GetViewMatrix() const override; + inline const Nz::Recti& GetViewport() const override; + inline float GetZFar() const override; + inline float GetZNear() const override; inline void SetFOV(float fov); inline void SetLayer(unsigned int layer); diff --git a/include/Nazara/Core/Hash/Whirlpool.hpp b/include/Nazara/Core/Hash/Whirlpool.hpp index 600e23b25..f7922254d 100644 --- a/include/Nazara/Core/Hash/Whirlpool.hpp +++ b/include/Nazara/Core/Hash/Whirlpool.hpp @@ -23,8 +23,8 @@ namespace Nz void Begin() override; ByteArray End() override; - std::size_t GetDigestLength() const; - const char* GetHashName() const; + std::size_t GetDigestLength() const override; + const char* GetHashName() const override; private: HashWhirlpool_state* m_state; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 76bff6926..fecd507be 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -42,7 +42,7 @@ namespace Nz void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; - void Clear(bool fully = false); + void Clear(bool fully = false) override; struct MeshDataComparator { diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 3a5d3ef33..9a17f5d2f 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -44,7 +44,7 @@ namespace Nz void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; - void Clear(bool fully = false); + void Clear(bool fully = false) override; void Sort(const AbstractViewer* viewer); diff --git a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp index b40e4f610..42449712c 100644 --- a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp +++ b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp @@ -19,7 +19,7 @@ namespace Nz GuillotineTextureAtlas() = default; ~GuillotineTextureAtlas() = default; - UInt32 GetStorage() const; + UInt32 GetStorage() const override; private: AbstractImage* ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const override; diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index 34dcbb137..76b834f6e 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -33,7 +33,7 @@ namespace Nz void AddController(ParticleControllerRef controller); void AddEmitter(ParticleEmitter* emitter); void AddGenerator(ParticleGeneratorRef generator); - void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const; + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const override; void ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime); diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 059d6b835..6ae25923e 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -54,7 +54,7 @@ namespace Nz bool HasAnimation() const; - bool IsAnimated() const; + bool IsAnimated() const override; bool IsAnimationEnabled() const; bool LoadFromFile(const String& filePath, const SkeletalModelParameters& params = SkeletalModelParameters()); diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 3db143292..3e3d14164 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -225,7 +225,7 @@ namespace Nz public: NullGeom(); - void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const; + void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const override; GeomType GetType() const override; diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index c197f50c0..798e441ee 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -43,12 +43,12 @@ namespace Nz void Detach(AttachmentPoint attachmentPoint, UInt8 index); unsigned int GetHeight() const override; - RenderTargetParameters GetParameters() const; + RenderTargetParameters GetParameters() const override; Vector2ui GetSize() const; unsigned int GetWidth() const override; bool IsComplete() const; - bool IsRenderable() const; + bool IsRenderable() const override; inline bool IsValid() const; bool Lock() const; diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index 0e283151b..d9889d803 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -46,11 +46,11 @@ namespace Nz void EnableVerticalSync(bool enabled); - unsigned int GetHeight() const; - RenderTargetParameters GetParameters() const; - unsigned int GetWidth() const; + unsigned int GetHeight() const override; + RenderTargetParameters GetParameters() const override; + unsigned int GetWidth() const override; - bool IsRenderable() const; + bool IsRenderable() const override; bool IsValid() const; void SetFramerateLimit(unsigned int limit); diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 22b52f293..68fdc1daa 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -24,7 +24,7 @@ namespace Nz SimpleTextDrawer(SimpleTextDrawer&& drawer); virtual ~SimpleTextDrawer(); - const Rectui& GetBounds() const; + const Rectui& GetBounds() const override; unsigned int GetCharacterSize() const; const Color& GetColor() const; Font* GetFont() const; diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 4cf99fee7..2aca17976 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -180,7 +180,7 @@ namespace Nz return true; } - unsigned int Read(void* buffer, unsigned int sampleCount) + unsigned int Read(void* buffer, unsigned int sampleCount) override { // Si la musique a été demandée en mono, nous devons la convertir à la volée lors de la lecture if (m_mixToMono) From 1d04ac8f1340007fa962d39a32c12925e3f6cefb Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:20:07 +0100 Subject: [PATCH 027/229] First implementation of Posix Network Former-commit-id: 2b73870d8eef4dc92038224164396390ac43df46 --- src/Nazara/Network/AbstractSocket.cpp | 4 +- src/Nazara/Network/IpAddress.cpp | 2 + src/Nazara/Network/Network.cpp | 2 + src/Nazara/Network/Posix/IpAddressImpl.cpp | 309 +++++++++ src/Nazara/Network/Posix/IpAddressImpl.hpp | 32 + src/Nazara/Network/Posix/SocketImpl.cpp | 746 +++++++++++++++++++++ src/Nazara/Network/Posix/SocketImpl.hpp | 68 ++ src/Nazara/Network/TcpClient.cpp | 2 + src/Nazara/Network/TcpServer.cpp | 4 +- src/Nazara/Network/UdpSocket.cpp | 2 + 10 files changed, 1169 insertions(+), 2 deletions(-) create mode 100644 src/Nazara/Network/Posix/IpAddressImpl.cpp create mode 100644 src/Nazara/Network/Posix/IpAddressImpl.hpp create mode 100644 src/Nazara/Network/Posix/SocketImpl.cpp create mode 100644 src/Nazara/Network/Posix/SocketImpl.hpp diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index d86f93501..1406741ff 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -9,6 +9,8 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include +#elif defined(NAZARA_PLATFORM_POSIX) +#include #else #error Missing implementation: Socket #endif @@ -105,4 +107,4 @@ namespace Nz m_handle = handle; OnOpened(); } -} \ No newline at end of file +} diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index b44412aca..d40e2a581 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -12,6 +12,8 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include +#elif defined(NAZARA_PLATFORM_POSIX) +#include #else #error Missing implementation: Network #endif diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp index ffe4842ca..d2f0d0d51 100644 --- a/src/Nazara/Network/Network.cpp +++ b/src/Nazara/Network/Network.cpp @@ -12,6 +12,8 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include +#elif defined(NAZARA_PLATFORM_POSIX) +#include #else #error Missing implementation: Network #endif diff --git a/src/Nazara/Network/Posix/IpAddressImpl.cpp b/src/Nazara/Network/Posix/IpAddressImpl.cpp new file mode 100644 index 000000000..1e4f6a89e --- /dev/null +++ b/src/Nazara/Network/Posix/IpAddressImpl.cpp @@ -0,0 +1,309 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace Detail + { + using addrinfoImpl = addrinfo; + + int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results) + { + return getaddrinfo(hostname.GetConstBuffer(), service.GetConstBuffer(), hints, results); + } + + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, int flags) + { + std::array hostnameBuffer; + std::array serviceBuffer; + + int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); + if (result == 0) + { + if (hostname) + hostname->Set(hostnameBuffer.data()); + + if (service) + service->Set(serviceBuffer.data()); + } + + return result; + } + + void FreeAddressInfo(addrinfoImpl* results) + { + freeaddrinfo(results); + } + + IpAddress::IPv4 convertSockaddrToIPv4(const in_addr& addr) + { + union byteToInt + { + UInt8 b[sizeof(uint32_t)]; + uint32_t i; + }; + + byteToInt hostOrder; + hostOrder.i = ntohl(addr.s_addr); + + return { hostOrder.b[3], hostOrder.b[2], hostOrder.b[1], hostOrder.b[0] }; + } + + IpAddress::IPv6 convertSockaddr6ToIPv6(const in6_addr& addr) + { + union byteToInt + { + UInt8 b[sizeof(uint32_t)]; + uint32_t i; + }; + + IpAddress::IPv6 ipv6Addr; + + for (auto i = 0; i < 4; ++i) + { + byteToInt hostOrder; + hostOrder.i = 0; + std::copy(addr.s6_addr + 4 * i, addr.s6_addr + 4 * (i + 1), hostOrder.b); + ipv6Addr[2 * i] = (hostOrder.b[3] << 8) + hostOrder.b[2]; + ipv6Addr[2 * i + 1] = (hostOrder.b[1] << 8) + hostOrder.b[0]; + } + + return ipv6Addr; + } + } + + IpAddress IpAddressImpl::FromAddrinfo(const addrinfo* info) + { + switch (info->ai_family) + { + case AF_INET: + { + sockaddr_in* ipv4 = reinterpret_cast(info->ai_addr); + + return FromSockAddr(ipv4); + } + + case AF_INET6: + { + sockaddr_in6* ipv6 = reinterpret_cast(info->ai_addr); + + return FromSockAddr(ipv6); + } + } + + return IpAddress::Invalid; + } + + IpAddress IpAddressImpl::FromSockAddr(const sockaddr* address) + { + switch (address->sa_family) + { + case AF_INET: + return FromSockAddr(reinterpret_cast(address)); + + case AF_INET6: + return FromSockAddr(reinterpret_cast(address)); + } + + return IpAddress::Invalid; + } + + IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in* addressv4) + { + IpAddress::IPv4 ip4Address = Detail::convertSockaddrToIPv4(addressv4->sin_addr); + return IpAddress(ip4Address, ntohs(addressv4->sin_port)); + } + + IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in6* addressv6) + { + IpAddress::IPv6 ip6Address = Detail::convertSockaddr6ToIPv6(addressv6->sin6_addr); + return IpAddress(ip6Address, ntohs(addressv6->sin6_port)); + } + + bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error) + { + SockAddrBuffer socketAddress; + socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data()); + + if (Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service, NI_NUMERICSERV) != 0) + { + if (error) + *error = TranslateEAIErrorToResolveError(errno); + + return false; + } + + if (error) + *error = ResolveError_NoError; + + return true; + } + + std::vector IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error) + { + std::vector results; + + Detail::addrinfoImpl hints; + std::memset(&hints, 0, sizeof(Detail::addrinfoImpl)); + hints.ai_family = SocketImpl::TranslateNetProtocolToAF(procol); + hints.ai_flags = AI_CANONNAME; + hints.ai_socktype = SOCK_STREAM; + + Detail::addrinfoImpl* servinfo; + if (Detail::GetAddressInfo(hostname, service, &hints, &servinfo) != 0) + { + if (error) + *error = TranslateEAIErrorToResolveError(errno); + + return results; + } + + CallOnExit onExit([servinfo]() + { + Detail::FreeAddressInfo(servinfo); + }); + + // loop through all the results and connect to the first we can + for (Detail::addrinfoImpl* p = servinfo; p != nullptr; p = p->ai_next) + { + HostnameInfo result; + result.address = FromAddrinfo(p); + result.canonicalName = String::Unicode(p->ai_canonname); + result.protocol = TranslatePFToNetProtocol(p->ai_family); + result.socketType = TranslateSockToNetProtocol(p->ai_socktype); + + results.push_back(result); + } + + if (error) + *error = ResolveError_NoError; + + return results; + } + + socklen_t IpAddressImpl::ToSockAddr(const IpAddress& ipAddress, void* buffer) + { + if (ipAddress.IsValid()) + { + switch (ipAddress.GetProtocol()) + { + case NetProtocol_IPv4: + { + sockaddr_in* socketAddress = reinterpret_cast(buffer); + + std::memset(socketAddress, 0, sizeof(sockaddr_in)); + socketAddress->sin_family = AF_INET; + socketAddress->sin_port = htons(ipAddress.GetPort()); + socketAddress->sin_addr.s_addr = htonl(ipAddress.ToUInt32()); + + return sizeof(sockaddr_in); + } + + case NetProtocol_IPv6: + { + sockaddr_in6* socketAddress = reinterpret_cast(buffer); + + std::memset(socketAddress, 0, sizeof(sockaddr_in6)); + socketAddress->sin6_family = AF_INET6; + socketAddress->sin6_port = htons(ipAddress.GetPort()); + + IpAddress::IPv6 address = ipAddress.ToIPv6(); + for (unsigned int i = 0; i < 8; ++i) + { + UInt16 networkOrder = htons(address[i]); + socketAddress->sin6_addr.s6_addr[2 * i] = networkOrder / 256; + socketAddress->sin6_addr.s6_addr[2 * i + 1] = networkOrder % 256; + } + + return sizeof(sockaddr_in6); + } + + default: + NazaraInternalError("Unhandled ip protocol (0x" + String::Number(ipAddress.GetProtocol()) + ')'); + break; + } + } + + NazaraError("Invalid ip address"); + return 0; + } + + NetProtocol IpAddressImpl::TranslatePFToNetProtocol(int family) + { + switch (family) + { + case PF_INET: + return NetProtocol_IPv4; + + case PF_INET6: + return NetProtocol_IPv6; + + default: + return NetProtocol_Unknown; + } + } + + SocketType IpAddressImpl::TranslateSockToNetProtocol(int socketType) + { + switch (socketType) + { + case SOCK_STREAM: + return SocketType_TCP; + + case SOCK_DGRAM: + return SocketType_UDP; + + case SOCK_RAW: + return SocketType_Raw; + + default: + return SocketType_Unknown; + } + } + + ResolveError IpAddressImpl::TranslateEAIErrorToResolveError(int error) + { + // http://man7.org/linux/man-pages/man3/gai_strerror.3.html + switch (error) + { + case 0: + return ResolveError_NoError; + + // Engine error + case EAI_BADFLAGS: + case EAI_SYSTEM: + return ResolveError_Internal; + + case EAI_FAMILY: + case EAI_SERVICE: + case EAI_SOCKTYPE: + return ResolveError_ProtocolNotSupported; + + case EAI_NONAME: + return ResolveError_NotFound; + + case EAI_FAIL: + return ResolveError_NonRecoverable; + + case EAI_NODATA: + return ResolveError_NotInitialized; + + case EAI_MEMORY: + return ResolveError_ResourceError; + + case EAI_AGAIN: + return ResolveError_TemporaryFailure; + } + + NazaraWarning("Unhandled EAI error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ") as " + gai_strerror(error)); + return ResolveError_Unknown; + } +} diff --git a/src/Nazara/Network/Posix/IpAddressImpl.hpp b/src/Nazara/Network/Posix/IpAddressImpl.hpp new file mode 100644 index 000000000..6ca919e78 --- /dev/null +++ b/src/Nazara/Network/Posix/IpAddressImpl.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + class IpAddressImpl + { + public: + using SockAddrBuffer = std::array; + + IpAddressImpl() = delete; + ~IpAddressImpl() = delete; + + static IpAddress FromAddrinfo(const addrinfo* info); + static IpAddress FromSockAddr(const sockaddr* address); + static IpAddress FromSockAddr(const sockaddr_in* addressv4); + static IpAddress FromSockAddr(const sockaddr_in6* addressv6); + + static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error); + static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error); + + static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer); + static NetProtocol TranslatePFToNetProtocol(int family); + static SocketType TranslateSockToNetProtocol(int socketType); + static ResolveError TranslateEAIErrorToResolveError(int error); + }; +} diff --git a/src/Nazara/Network/Posix/SocketImpl.cpp b/src/Nazara/Network/Posix/SocketImpl.cpp new file mode 100644 index 000000000..cf5a638cf --- /dev/null +++ b/src/Nazara/Network/Posix/SocketImpl.cpp @@ -0,0 +1,746 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + constexpr int SOCKET_ERROR = -1; + + SocketHandle SocketImpl::Accept(SocketHandle handle, IpAddress* address, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + socklen_t bufferLength = sizeof(sockaddr_in); + + SocketHandle newClient = accept(handle, reinterpret_cast(&nameBuffer), &bufferLength); + if (newClient != InvalidHandle) + { + if (address) + *address = IpAddressImpl::FromSockAddr(reinterpret_cast(&nameBuffer)); + + if (error) + *error = SocketError_NoError; + } + else + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + } + + return newClient; + } + + SocketState SocketImpl::Bind(SocketHandle handle, const IpAddress& address, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(address.IsValid(), "Invalid address"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); + + if (bind(handle, reinterpret_cast(&nameBuffer), bufferLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return SocketState_NotConnected; + } + + if (error) + *error = SocketError_NoError; + + return SocketState_Bound; + } + + SocketHandle SocketImpl::Create(NetProtocol protocol, SocketType type, SocketError* error) + { + NazaraAssert(protocol != NetProtocol_Any, "Any protocol is not supported for socket creation"); + NazaraAssert(type <= SocketType_Max, "Type has value out of enum"); + + SocketHandle handle = socket(TranslateNetProtocolToAF(protocol), TranslateSocketTypeToSock(type), 0); + if (handle == InvalidHandle && error != nullptr) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return handle; + } + + void SocketImpl::Close(SocketHandle handle) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + if (close(handle) == SOCKET_ERROR) + NazaraWarning("Failed to close socket: " + Error::GetLastSystemError(GetLastErrorCode())); + } + + void SocketImpl::ClearErrorCode(SocketHandle handle) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + if (GetLastError(handle, nullptr) < 0) + NazaraWarning("Failed to clear socket error code: " + Error::GetLastSystemError(GetLastErrorCode())); + } + + SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(address.IsValid(), "Invalid address"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); + + if (error) + *error = SocketError_NoError; + + // Clear socket error status + ClearErrorCode(handle); + + if (connect(handle, reinterpret_cast(nameBuffer.data()), bufferLength) == SOCKET_ERROR) + { + int errorCode = GetLastErrorCode(); + switch (errorCode) //< Check for "normal errors" first + { + case EALREADY: + case EINPROGRESS: + return SocketState_Connecting; + + case EISCONN: + return SocketState_Connected; + } + + if (error) + { + if (errorCode == EADDRNOTAVAIL) + *error = SocketError_ConnectionRefused; //< ConnectionRefused seems more legit than AddressNotAvailable in connect case + else + *error = TranslateErrnoToResolveError(errorCode); + } + + return SocketState_NotConnected; + } + + return SocketState_Connected; + } + + SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error) + { + SocketState state = Connect(handle, address, error); + if (state == SocketState_Connecting) + { + // http://developerweb.net/viewtopic.php?id=3196 + fd_set localSet; + FD_ZERO(&localSet); + FD_SET(handle, &localSet); + + timeval tv; + tv.tv_sec = static_cast(msTimeout / 1000ULL); + tv.tv_usec = static_cast((msTimeout % 1000ULL) * 1000ULL); + + int ret = select(0, nullptr, &localSet, &localSet, (msTimeout > 0) ? &tv : nullptr); + if (ret == SOCKET_ERROR) + { + int code = GetLastErrorCode(handle, error); + if (code < 0) //< GetLastErrorCode() failed + return SocketState_NotConnected; + + if (code) + { + if (error) + *error = TranslateErrnoToResolveError(code); + + return SocketState_NotConnected; + } + } + else if (ret == 0) + { + if (error) + *error = SocketError_TimedOut; + + return SocketState_NotConnected; + } + else + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return SocketState_NotConnected; + } + + if (error) + *error = SocketError_NoError; + + state = SocketState_Connected; + } + + return state; + } + + bool SocketImpl::Initialize() + { + return true; + } + + SocketError SocketImpl::GetLastError(SocketHandle handle, SocketError* error) + { + int code = GetLastErrorCode(handle, error); + if (code < 0) + return SocketError_Internal; + + return TranslateErrnoToResolveError(code); + } + + int SocketImpl::GetLastErrorCode() + { + return errno; + } + + int SocketImpl::GetLastErrorCode(SocketHandle handle, SocketError* error) + { + int code; + unsigned int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_ERROR, &code, &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return -1; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + SocketState SocketImpl::Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(address.IsValid(), "Invalid address"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); + + if (bind(handle, reinterpret_cast(&nameBuffer), bufferLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return SocketState_NotConnected; + } + + if (listen(handle, queueSize) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return SocketState_NotConnected; + } + + if (error) + *error = SocketError_NoError; + + return SocketState_Bound; + } + + unsigned int SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + u_long availableBytes; + if (ioctl(handle, FIONREAD, &availableBytes) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return 0; + } + + if (error) + *error = SocketError_NoError; + + return availableBytes; + } + + bool SocketImpl::QueryBroadcasting(SocketHandle handle, SocketError* error) + { + bool code; + unsigned int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &code, &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + bool SocketImpl::QueryKeepAlive(SocketHandle handle, SocketError* error) + { + bool code; + unsigned int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &code, &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + unsigned int SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) + { + unsigned int code; + unsigned int codeLength = sizeof(code); + + if (getsockopt(handle, IPPROTO_IP, IP_MTU, &code, &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return -1; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + bool SocketImpl::QueryNoDelay(SocketHandle handle, SocketError* error) + { + bool code; + unsigned int codeLength = sizeof(code); + + if (getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &code, &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + IpAddress SocketImpl::QueryPeerAddress(SocketHandle handle, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + socklen_t bufferLength = sizeof(sockaddr_in); + + if (getpeername(handle, reinterpret_cast(nameBuffer.data()), &bufferLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return IpAddress(); + } + + if (error) + *error = SocketError_NoError; + + return IpAddressImpl::FromSockAddr(reinterpret_cast(nameBuffer.data())); + } + + IpAddress SocketImpl::QuerySocketAddress(SocketHandle handle, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + socklen_t bufferLength = sizeof(sockaddr_in); + + if (getsockname(handle, reinterpret_cast(nameBuffer.data()), &bufferLength) == SOCKET_ERROR) + { + if (error) + { + int errorCode = GetLastErrorCode(); + if (errorCode == EINVAL) + *error = SocketError_NoError; + else + *error = TranslateErrnoToResolveError(errorCode); + } + + return IpAddress(); + } + + if (error) + *error = SocketError_NoError; + + return IpAddressImpl::FromSockAddr(reinterpret_cast(nameBuffer.data())); + } + + + bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + int byteRead = recv(handle, reinterpret_cast(buffer), length, 0); + if (byteRead == SOCKET_ERROR) + { + int errorCode = GetLastErrorCode(); + switch (errorCode) + { + case EWOULDBLOCK: + { + // If we have no data and are not blocking, return true with 0 byte read + byteRead = 0; + break; + } + + default: + { + if (error) + *error = TranslateErrnoToResolveError(errorCode); + + return false; //< Error + } + } + } + else if (byteRead == 0) + { + if (error) + *error = SocketError_ConnectionClosed; + + return false; //< Connection has been closed + } + + if (read) + *read = byteRead; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + socklen_t bufferLength = sizeof(sockaddr_in); + + IpAddress senderIp; + + int byteRead = recvfrom(handle, buffer, length, 0, reinterpret_cast(&nameBuffer), &bufferLength); + if (byteRead == SOCKET_ERROR) + { + int errorCode = GetLastErrorCode(); + switch (errorCode) + { + case EWOULDBLOCK: + { + // If we have no data and are not blocking, return true with 0 byte read + byteRead = 0; + senderIp = IpAddress::Invalid; + break; + } + + default: + { + if (error) + *error = TranslateErrnoToResolveError(errorCode); + + return false; //< Error + } + } + } + else if (byteRead == 0) + { + if (error) + *error = SocketError_ConnectionClosed; + + return false; //< Connection closed + } + else // else we received something + senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast(&nameBuffer)); + + if (from) + *from = senderIp; + + if (read) + *read = byteRead; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + int byteSent = send(handle, reinterpret_cast(buffer), length, 0); + if (byteSent == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (sent) + *sent = byteSent; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); + + int byteSent = sendto(handle, reinterpret_cast(buffer), length, 0, reinterpret_cast(nameBuffer.data()), bufferLength); + if (byteSent == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (sent) + *sent = byteSent; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetBlocking(SocketHandle handle, bool blocking, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + u_long block = (blocking) ? 0 : 1; + if (ioctl(handle, FIONBIO, &block) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + bool option = broadcasting; + if (setsockopt(handle, SOL_SOCKET, SO_BROADCAST, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + int keepAlive = enabled ? 1 : 0; + int keepIdle = msTime / 1000; // Linux works with seconds. + int keepInterval = msInterval / 1000; // Linux works with seconds. + + if (setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &keepAlive , sizeof(keepAlive)) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (setsockopt(handle, IPPROTO_TCP, TCP_KEEPIDLE, &keepIdle, sizeof(keepIdle)) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (setsockopt(handle, IPPROTO_TCP, TCP_KEEPINTVL, &keepInterval, sizeof(keepInterval)) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + int option = nodelay ? 1 : 0; + if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + SocketError SocketImpl::TranslateErrnoToResolveError(int error) + { + switch (error) + { + case 0: + return SocketError_NoError; + + // Engine error + case EACCES: + case EBADF: + case EINVAL: + case EFAULT: + case ENOTSOCK: + case EPROTOTYPE: + return SocketError_Internal; + + case EADDRNOTAVAIL: + case EADDRINUSE: + return SocketError_AddressNotAvailable; + + case EAFNOSUPPORT: + case EPFNOSUPPORT: + case EOPNOTSUPP: + case EPROTONOSUPPORT: + case ESOCKTNOSUPPORT: + return SocketError_NotSupported; + + // Those are not errors and should have been handled before the call + case EALREADY: + case EISCONN: + case EWOULDBLOCK: + return SocketError_Internal; + + case ECONNREFUSED: + return SocketError_ConnectionRefused; + + case EMSGSIZE: + return SocketError_DatagramSize; + + case EMFILE: + case ENOBUFS: + case ENOMEM: + return SocketError_ResourceError; + + case ENOTCONN: + case ESHUTDOWN: + return SocketError_ConnectionClosed; + + case EHOSTUNREACH: + return SocketError_UnreachableHost; + + case ENETDOWN: + case ENETUNREACH: + return SocketError_NetworkError; + + case ENODATA: + return SocketError_NotInitialized; + + case ETIMEDOUT: + return SocketError_TimedOut; + } + + NazaraWarning("Unhandled POSIX error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ')'); + return SocketError_Unknown; + } + + int SocketImpl::TranslateNetProtocolToAF(NetProtocol protocol) + { + NazaraAssert(protocol <= NetProtocol_Max, "Protocol has value out of enum"); + + static int addressFamily[] = { + AF_UNSPEC, //< NetProtocol_Any + AF_INET, //< NetProtocol_IPv4 + AF_INET6, //< NetProtocol_IPv6 + -1 //< NetProtocol_Unknown + }; + static_assert(sizeof(addressFamily) / sizeof(int) == NetProtocol_Max + 1, "Address family array is incomplete"); + + return addressFamily[protocol]; + } + + int SocketImpl::TranslateSocketTypeToSock(SocketType type) + { + NazaraAssert(type <= SocketType_Max, "Socket type has value out of enum"); + + static int socketType[] = { + SOCK_RAW, //< SocketType_Raw + SOCK_STREAM, //< SocketType_TCP + SOCK_DGRAM, //< SocketType_UDP + -1 //< SocketType_Unknown + }; + static_assert(sizeof(socketType) / sizeof(int) == SocketType_Max + 1, "Socket type array is incomplete"); + + return socketType[type]; + } + + void SocketImpl::Uninitialize() + { + } + + SocketHandle SocketImpl::InvalidHandle = -1; + SocketImpl::socketID SocketImpl::s_socket; +} diff --git a/src/Nazara/Network/Posix/SocketImpl.hpp b/src/Nazara/Network/Posix/SocketImpl.hpp new file mode 100644 index 000000000..c23b4d3e4 --- /dev/null +++ b/src/Nazara/Network/Posix/SocketImpl.hpp @@ -0,0 +1,68 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + class SocketImpl + { + public: + SocketImpl() = delete; + ~SocketImpl() = delete; + + static SocketHandle Accept(SocketHandle handle, IpAddress* address, SocketError* error); + + static SocketState Bind(SocketHandle handle, const IpAddress& address, SocketError* error); + + static SocketHandle Create(NetProtocol protocol, SocketType type, SocketError* error); + + static void ClearErrorCode(SocketHandle handle); + static void Close(SocketHandle handle); + + static SocketState Connect(SocketHandle handle, const IpAddress& address, SocketError* error); + static SocketState Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error); + + static bool Initialize(); + + static SocketError GetLastError(SocketHandle handle, SocketError* error = nullptr); + static int GetLastErrorCode(); + static int GetLastErrorCode(SocketHandle handle, SocketError* error = nullptr); + + static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error); + + static unsigned int QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); + static bool QueryBroadcasting(SocketHandle handle, SocketError* error = nullptr); + static bool QueryKeepAlive(SocketHandle handle, SocketError* error = nullptr); + static unsigned int QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); + static bool QueryNoDelay(SocketHandle handle, SocketError* error = nullptr); + static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); + static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); + + static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error); + static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error); + + static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error); + static bool SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error); + + static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr); + static bool SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error = nullptr); + static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr); + static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr); + + static SocketError TranslateErrnoToResolveError(int error); + static int TranslateNetProtocolToAF(NetProtocol protocol); + static int TranslateSocketTypeToSock(SocketType type); + + static void Uninitialize(); + + static SocketHandle InvalidHandle; + + private: + using socketID = int; + static socketID s_socket; + }; +} diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index b91dfaffd..6bb26aef8 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -10,6 +10,8 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include +#elif defined(NAZARA_PLATFORM_POSIX) +#include #else #error Missing implementation: Socket #endif diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp index 096603b8f..b5995b6f5 100644 --- a/src/Nazara/Network/TcpServer.cpp +++ b/src/Nazara/Network/TcpServer.cpp @@ -11,6 +11,8 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include +#elif defined(NAZARA_PLATFORM_POSIX) +#include #else #error Missing implementation: Socket #endif @@ -60,4 +62,4 @@ namespace Nz m_boundAddress = IpAddress::Invalid; } -} \ No newline at end of file +} diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index fb813b3d6..0ecd423bb 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -7,6 +7,8 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include +#elif defined(NAZARA_PLATFORM_POSIX) +#include #else #error Missing implementation: Socket #endif From 007b40b1b3f7b8f33e7d66926353001102ac9aa2 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:28:13 +0100 Subject: [PATCH 028/229] Documentation for Algorithm + constexpr Former-commit-id: d77905d0ee9a2dde655f548bd175042aa3f5d22d --- include/Nazara/Math/Algorithm.hpp | 32 ++-- include/Nazara/Math/Algorithm.inl | 307 ++++++++++++++++++++++++++---- 2 files changed, 286 insertions(+), 53 deletions(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 841c3569a..c7d4dd024 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -30,32 +30,32 @@ namespace Nz { - template T Approach(T value, T objective, T increment); + template constexpr T Approach(T value, T objective, T increment); template constexpr T Clamp(T value, T min, T max); - template T CountBits(T value); + template constexpr T CountBits(T value); template constexpr T FromDegrees(T degrees); template constexpr T FromRadians(T radians); template constexpr T DegreeToRadian(T degrees); - template T GetNearestPowerOfTwo(T number); - unsigned int GetNumberLength(signed char number); - unsigned int GetNumberLength(unsigned char number); + template constexpr T GetNearestPowerOfTwo(T number); + constexpr unsigned int GetNumberLength(signed char number); + constexpr unsigned int GetNumberLength(unsigned char number); unsigned int GetNumberLength(int number); - unsigned int GetNumberLength(unsigned int number); + constexpr unsigned int GetNumberLength(unsigned int number); unsigned int GetNumberLength(long long number); - unsigned int GetNumberLength(unsigned long long number); + constexpr unsigned int GetNumberLength(unsigned long long number); unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); - template unsigned int IntegralLog2(T number); - template unsigned int IntegralLog2Pot(T pot); - unsigned int IntegralPow(unsigned int base, unsigned int exponent); - template T Lerp(T from, T to, T2 interpolation); - template T MultiplyAdd(T x, T y, T z); - template T NormalizeAngle(T angle); - template bool NumberEquals(T a, T b); - template bool NumberEquals(T a, T b, T maxDifference); + template constexpr unsigned int IntegralLog2(T number); + template constexpr unsigned int IntegralLog2Pot(T pot); + constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent); + template constexpr T Lerp(const T& from, const T& to, const T2& interpolation); + template constexpr T MultiplyAdd(T x, T y, T z); + template constexpr T NormalizeAngle(T angle); + template constexpr bool NumberEquals(T a, T b); + template constexpr bool NumberEquals(T a, T b, T maxDifference); String NumberToString(long long number, UInt8 radix = 10); - template T RadianToDegree(T radians); + template constexpr T RadianToDegree(T radians); long long StringToNumber(String str, UInt8 radix = 10, bool* ok = nullptr); template constexpr T ToDegrees(T angle); template constexpr T ToRadians(T angle); diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 1a4fceded..c42a1b8b5 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -98,10 +98,18 @@ namespace Nz } } + /*! + * \brief Approaches the objective, beginning with value and with increment + * \return The nearest value of the objective you can get with the value and the increment for one step + * + * \param value Initial value + * \param objective Target value + * \parma increment One step value + */ + template - T Approach(T value, T objective, T increment) + constexpr T Approach(T value, T objective, T increment) { - ///TODO: Marquer comme constexpr en C++14 if (value < objective) return std::min(value + increment, objective); else if (value > objective) @@ -110,14 +118,30 @@ namespace Nz return value; } + /*! + * \brief Clamps value between min and max and returns the expected value + * \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval + * + * \param value Value to clamp + * \param min Minimum of the interval + * \param max Maximum of the interval + */ + template constexpr T Clamp(T value, T min, T max) { return std::max(std::min(value, max), min); } + /*! + * \brief Gets number of bits set in the number + * \return The number of bits set to 1 + * + * \param value The value to count bits + */ + template - T CountBits(T value) + constexpr T CountBits(T value) { // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan unsigned int count = 0; @@ -130,12 +154,26 @@ namespace Nz return count; } + /*! + * \brief Converts degree to radian + * \return The representation in radian of the angle in degree (0..2*pi) + * + * \param degrees Angle in degree (this is expected between 0..360) + */ + template constexpr T DegreeToRadian(T degrees) { return degrees * T(M_PI/180.0); } + /*! + * \brief Gets the unit from degree and convert it according to NAZARA_MATH_ANGLE_RADIAN + * \return Express the degrees + * + * \param degrees Convert degree to NAZARA_MATH_ANGLE_RADIAN unit + */ + template constexpr T FromDegrees(T degrees) { @@ -146,6 +184,13 @@ namespace Nz #endif } + /*! + * \brief Gets the unit from radian and convert it according to NAZARA_MATH_ANGLE_RADIAN + * \return Express the radians + * + * \param radians Convert radian to NAZARA_MATH_ANGLE_RADIAN unit + */ + template constexpr T FromRadians(T radians) { @@ -156,22 +201,33 @@ namespace Nz #endif } + /*! + * \brief Gets the nearest power of two for the number + * \return First power of two containing the number + * + * \param number Number to get nearest power + */ + template - T GetNearestPowerOfTwo(T number) + constexpr T GetNearestPowerOfTwo(T number) { - ///TODO: Marquer comme constexpr en C++14 T x = 1; - // Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux while (x < number) - x <<= 1; + x <<= 1; // We multiply by 2 return x; } - inline unsigned int GetNumberLength(signed char number) + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + * + * \param number Number to get number of digits + */ + + constexpr unsigned int GetNumberLength(signed char number) { - ///TODO: Marquer comme constexpr en C++14 - // Le standard définit le char comme étant codé sur un octet + // Char is expected to be 1 byte static_assert(sizeof(number) == 1, "Signed char must be one byte-sized"); if (number >= 100) @@ -188,10 +244,16 @@ namespace Nz return 4; } - inline unsigned int GetNumberLength(unsigned char number) + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + * + * \param number Number to get number of digits + */ + + constexpr unsigned int GetNumberLength(unsigned char number) { - ///TODO: Marquer comme constexpr en C++14 - // Le standard définit le char comme étant codé sur un octet + // Char is expected to be 1 byte static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized"); if (number >= 100) @@ -202,6 +264,13 @@ namespace Nz return 1; } + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + * + * \param number Number to get number of digits + */ + inline unsigned int GetNumberLength(int number) { if (number == 0) @@ -210,7 +279,14 @@ namespace Nz return static_cast(std::log10(std::abs(number))) + (number < 0 ? 2 : 1); } - inline unsigned int GetNumberLength(unsigned int number) + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + * + * \param number Number to get number of digits + */ + + constexpr unsigned int GetNumberLength(unsigned int number) { if (number == 0) return 1; @@ -218,6 +294,13 @@ namespace Nz return static_cast(std::log10(number))+1; } + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + * + * \param number Number to get number of digits + */ + inline unsigned int GetNumberLength(long long number) { if (number == 0) @@ -226,7 +309,14 @@ namespace Nz return static_cast(std::log10(std::abs(number))) + (number < 0 ? 2 : 1); } - inline unsigned int GetNumberLength(unsigned long long number) + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + * + * \param number Number to get number of digits + */ + + constexpr unsigned int GetNumberLength(unsigned long long number) { if (number == 0) return 1; @@ -234,40 +324,90 @@ namespace Nz return static_cast(std::log10(number)) + 1; } + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + 1 for the dot + * + * \param number Number to get number of digits + * \param precision Number of digit after the dot + */ + inline unsigned int GetNumberLength(float number, UInt8 precision) { - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) - return GetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point + // The imprecision of floats need a cast (log10(9.99999) = 0.99999) + return GetNumberLength(static_cast(number)) + precision + 1; // Plus one for the dot } + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + 1 for the dot + * + * \param number Number to get number of digits + * \param precision Number of digit after the dot + */ + inline unsigned int GetNumberLength(double number, UInt8 precision) { - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) - return GetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point + // The imprecision of floats need a cast (log10(9.99999) = 0.99999) + return GetNumberLength(static_cast(number)) + precision + 1; // Plus one for the dot } + /*! + * \brief Gets the number of digits to represent the number in base 10 + * \return Number of digits + 1 for the dot + * + * \param number Number to get number of digits + * \param precision Number of digit after the dot + */ + inline unsigned int GetNumberLength(long double number, UInt8 precision) { - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) - return GetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point + // The imprecision of floats need a cast (log10(9.99999) = 0.99999) + return GetNumberLength(static_cast(number)) + precision + 1; // Plus one for the dot } + /*! + * \brief Gets the log in base 2 of integral number + * \return Log of the number (floor) + * + * \param number To get log in base 2 + * + * \remark If number is 0, 0 is returned + */ + template - unsigned int IntegralLog2(T number) + constexpr unsigned int IntegralLog2(T number) { - // Proxy nécessaire pour éviter un problème de surcharge + // Proxy needed to avoid an overload problem return Detail::IntegralLog2(number); } + /*! + * \brief Gets the log in base 2 of integral number, only works for power of two ! + * \return Log of the number + * + * \param number To get log in base 2 + * + * \remark Only works for power of two + * \remark If number is 0, 0 is returned + */ + template - unsigned int IntegralLog2Pot(T pot) + constexpr unsigned int IntegralLog2Pot(T pot) { return Detail::IntegralLog2Pot(pot); } - inline unsigned int IntegralPow(unsigned int base, unsigned int exponent) + /*! + * \brief Gets the power of integrals + * \return base^exponent for integral + * + * \param base Base of the exponentation + * \parma exponent Power for the base + */ + + constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent) { - ///TODO: Marquer comme constexpr en C++14 unsigned int r = 1; for (unsigned int i = 0; i < exponent; ++i) r *= base; @@ -275,8 +415,22 @@ namespace Nz return r; } + /*! + * \brief Interpolates the value to other one with a factor of interpolation + * \return A new value which is the interpolation of two values + * + * \param from Initial value + * \param to Target value + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraWarning is produced + * + * \see Lerp + */ + template - T Lerp(T from, T to, T2 interpolation) + constexpr T Lerp(const T& from, const T& to, const T2& interpolation) { #ifdef NAZARA_DEBUG if (interpolation < T2(0.0) || interpolation > T2(1.0)) @@ -286,15 +440,26 @@ namespace Nz return from + interpolation * (to - from); } + /*! + * \brief Multiplies X and Y, then add Z + * \return The result of X * Y + Z + * + * \param x is X + * \param y is Y + * \param z is Z + * + * \remark This function is meant to use a special instruction in CPU + */ + template - T MultiplyAdd(T x, T y, T z) + constexpr T MultiplyAdd(T x, T y, T z) { - return x*y + z; + return x * y + z; } #ifdef FP_FAST_FMAF template<> - inline float MultiplyAdd(float x, float y, float z) + constexpr float MultiplyAdd(float x, float y, float z) { return std::fmaf(x, y, z); } @@ -302,7 +467,7 @@ namespace Nz #ifdef FP_FAST_FMA template<> - inline double MultiplyAdd(double x, double y, double z) + constexpr double MultiplyAdd(double x, double y, double z) { return std::fma(x, y, z); } @@ -310,14 +475,21 @@ namespace Nz #ifdef FP_FAST_FMAL template<> - inline long double MultiplyAdd(long double x, long double y, long double z) + constexpr long double MultiplyAdd(long double x, long double y, long double z) { return std::fmal(x, y, z); } #endif + /*! + * \brief Normalizes the angle + * \return Normalized value between 0..2*(pi if radian or 180 if degrees) + * + * \param angle Angle to normalize + */ + template - T NormalizeAngle(T angle) + constexpr T NormalizeAngle(T angle) { #if NAZARA_MATH_ANGLE_RADIAN const T limit = T(M_PI); @@ -333,14 +505,31 @@ namespace Nz return angle - limit; } + /*! + * \brief Checks whether two numbers are equal + * \return true if they are equal within a certain epsilon + * + * \param a First value + * \param b Second value + */ + template - bool NumberEquals(T a, T b) + constexpr bool NumberEquals(T a, T b) { return NumberEquals(a, b, std::numeric_limits::epsilon()); } + /*! + * \brief Checks whether two numbers are equal + * \return true if they are equal within the max difference + * + * \param a First value + * \param b Second value + * \param maxDifference Epsilon of comparison (expected to be positive) + */ + template - bool NumberEquals(T a, T b, T maxDifference) + constexpr bool NumberEquals(T a, T b, T maxDifference) { if (b > a) std::swap(a, b); @@ -349,6 +538,17 @@ namespace Nz return diff <= maxDifference; } + /*! + * \brief Converts the number to String + * \return String representation of the number + * + * \param number Number to represent + * \param radix Base of the number + * + * \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior + * \remark With NAZARA_MATH_SAFE, a NazaraError is produced and String() is returned + */ + inline String NumberToString(long long number, UInt8 radix) { #if NAZARA_MATH_SAFE @@ -389,12 +589,31 @@ namespace Nz return str.Reverse(); } + /*! + * \brief Converts radian to degree + * \return The representation in degree of the angle in radian (0..360) + * + * \param radians Angle in radian (this is expected between 0..2*pi) + */ + template - T RadianToDegree(T radians) + constexpr T RadianToDegree(T radians) { return radians * T(180.0/M_PI); } + /*! + * \brief Converts the string to number + * \return Number which is represented by the string + * + * \param str String representation + * \param radix Base of the number + * \param ok Optional argument to know if convertion is correct + * + * \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior + * \remark With NAZARA_MATH_SAFE, a NazaraError is produced and 0 is returned + */ + inline long long StringToNumber(String str, UInt8 radix, bool* ok) { #if NAZARA_MATH_SAFE @@ -444,6 +663,13 @@ namespace Nz return (negative) ? -static_cast(total) : total; } + /*! + * \brief Gets the degree from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN + * \return Express in degrees + * + * \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to degrees + */ + template constexpr T ToDegrees(T angle) { @@ -454,6 +680,13 @@ namespace Nz #endif } + /*! + * \brief Gets the radian from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN + * \return Express in radians + * + * \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to radians + */ + template constexpr T ToRadians(T angle) { @@ -461,8 +694,8 @@ namespace Nz return angle; #else return DegreeToRadian(angle); + #endif } - #endif } #include From e2213cac613e9444e97a6f8e86bbb01d0bc5fa1f Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:29:07 +0100 Subject: [PATCH 029/229] Documentation for BoundingVolume & Box Former-commit-id: 0fc14422dc32677f329f95dc7a554127f1b8ba0a --- include/Nazara/Math/BoundingVolume.inl | 260 +++++++++++++- include/Nazara/Math/Box.hpp | 2 +- include/Nazara/Math/Box.inl | 466 +++++++++++++++++++++++-- 3 files changed, 682 insertions(+), 46 deletions(-) diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 13b41a63e..4cde59731 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -13,42 +13,108 @@ namespace Nz { + + /*! + * \class Nz::BoundingVolume + * \brief Math class that represents a bounding volume, a combination of a box and an oriented box + * + * \remark You need to call Update not to have undefined behaviour + */ + + /*! + * \brief Constructs a BoundingVolume object by default + * + * \remark extend is set to Extend_Null, aabb and obb are uninitialized + */ + template BoundingVolume::BoundingVolume() : extend(Extend_Null) { } + /*! + * \brief Constructs a BoundingVolume object from Extend + * \param Extend Extend of the volume part of enumeration Extend + * + * \remark Aabb and obb are uninitialized + */ + template BoundingVolume::BoundingVolume(Extend Extend) { Set(Extend); } + /*! + * \brief Constructs a BoundingVolume object from its position and sizes + * + * \param X X component of position + * \param Y Y component of position + * \param Z Z component of position + * \param Width Width of the box (following X) + * \param Height Height of the box (following Y) + * \param Depth Depth of the box (following Z) + * + * \remark Aabb is uninitialized + */ + template BoundingVolume::BoundingVolume(T X, T Y, T Z, T Width, T Height, T Depth) { Set(X, Y, Z, Width, Height, Depth); } + /*! + * \brief Constructs a BoundingVolume object from a box + * + * \param box Box object + * + * \remark Aabb is uninitialized + */ + template BoundingVolume::BoundingVolume(const Box& box) { Set(box); } + /*! + * \brief Constructs a BoundingVolume object from an oriented box + * + * \param orientedBox OrientedBox object + * + * \remark Aabb is uninitialized + */ + template BoundingVolume::BoundingVolume(const OrientedBox& orientedBox) { Set(orientedBox); } + /*! + * \brief Constructs a BoundingVolume object from two vectors representing point of the space + * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum + * + * \param vec1 First point + * \param vec2 Second point + * + * \remark Aabb is uninitialized + */ + template BoundingVolume::BoundingVolume(const Vector3& vec1, const Vector3& vec2) { Set(vec1, vec2); } + /*! + * \brief Constructs a BoundingVolume object from another type of BoundingVolume + * + * \param volume BoundingVolume of type U to convert to type T + */ + template template BoundingVolume::BoundingVolume(const BoundingVolume& volume) @@ -56,24 +122,46 @@ namespace Nz Set(volume); } + /*! + * \brief Checks whether the volume is finite + * \return true if extend is Extend_Finite + */ + template bool BoundingVolume::IsFinite() const { return extend == Extend_Finite; } + /*! + * \brief Checks whether the volume is infinite + * \return true if extend is Extend_Infinite + */ + template bool BoundingVolume::IsInfinite() const { return extend == Extend_Infinite; } + /*! + * \brief Checks whether the volume is null + * \return true if extend is Extend_Null + */ + template bool BoundingVolume::IsNull() const { return extend == Extend_Null; } + /*! + * \brief Makes the bounding volume infinite + * \return A reference to this bounding volume with Extend_Infinite for extend + * + * \see Infinite + */ + template BoundingVolume& BoundingVolume::MakeInfinite() { @@ -82,6 +170,13 @@ namespace Nz return *this; } + /*! + * \brief Makes the bounding volume null + * \return A reference to this bounding volume with Extend_Null for extend + * + * \see Null + */ + template BoundingVolume& BoundingVolume::MakeNull() { @@ -90,6 +185,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the extend of the bounding volume from Extend + * \return A reference to this bounding volume + * + * \param Extend New extend + * + * \remark This method is meant to be called with Extend_Infinite or Extend_Null + */ + template BoundingVolume& BoundingVolume::Set(Extend Extend) { @@ -98,6 +202,18 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the bounding volume + * \return A reference to this bounding volume + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Width Width of the oriented box (following X) + * \param Height Height of the oriented box (following Y) + * \param Depth Depth of the oriented box (following Z) + */ + template BoundingVolume& BoundingVolume::Set(T X, T Y, T Z, T Width, T Height, T Depth) { @@ -107,15 +223,29 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the bounding volume from another bounding volume + * \return A reference to this bounding volume + * + * \param volume The other bounding volume + */ + template BoundingVolume& BoundingVolume::Set(const BoundingVolume& volume) { - obb.Set(volume.obb); // Seul l'OBB est importante pour la suite + obb.Set(volume.obb); // Only OBB is important for the moment extend = volume.extend; return *this; } + /*! + * \brief Sets the components of the bounding volume from a box + * \return A reference to this bounding volume + * + * \param box Box object + */ + template BoundingVolume& BoundingVolume::Set(const Box& box) { @@ -125,6 +255,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the bounding volume from an oriented box + * \return A reference to this bounding volume + * + * \param orientedBox OrientedBox object + */ + template BoundingVolume& BoundingVolume::Set(const OrientedBox& orientedBox) { @@ -134,6 +271,14 @@ namespace Nz return *this; } + /*! + * \brief Sets a BoundingVolume object from two vectors representing point of the space + * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum + * + * \param vec1 First point + * \param vec2 Second point + */ + template BoundingVolume& BoundingVolume::Set(const Vector3& vec1, const Vector3& vec2) { @@ -143,6 +288,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the bounding volume from another type of BoundingVolume + * \return A reference to this bounding volume + * + * \param volume BoundingVolume of type U to convert its components + */ + template template BoundingVolume& BoundingVolume::Set(const BoundingVolume& volume) @@ -153,6 +305,13 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "BoundingVolume(localBox="")" if finite, or "BoundingVolume(Infinite)" or "BoundingVolume(Null)" + * + * \remark If enumeration is not defined in Extend, a NazaraError is thrown and "BoundingVolume(ERROR)" is returned + */ + template String BoundingVolume::ToString() const { @@ -173,6 +332,12 @@ namespace Nz return "BoundingVolume(ERROR)"; } + /*! + * \brief Updates the obb and the aabb of the bounding volume + * + * \param transformMatrix Matrix4 which represents the transformation to apply + */ + template void BoundingVolume::Update(const Matrix4& transformMatrix) { @@ -183,6 +348,12 @@ namespace Nz aabb.ExtendTo(obb(i)); } + /*! + * \brief Updates the obb and the aabb of the bounding volume + * + * \param translation Vector3 which represents the translation to apply + */ + template void BoundingVolume::Update(const Vector3& translation) { @@ -193,6 +364,13 @@ namespace Nz aabb.ExtendTo(obb(i)); } + /*! + * \brief Multiplies the lengths of the obb with the scalar + * \return A BoundingVolume where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar + * + * \param scale The scalar to multiply width, height and depth with + */ + template BoundingVolume BoundingVolume::operator*(T scalar) const { @@ -202,6 +380,13 @@ namespace Nz return volume; } + /*! + * \brief Multiplies the lengths of this bounding volume with the scalar + * \return A reference to this bounding volume where lengths are the product of these lengths and the scalar + * + * \param scalar The scalar to multiply width, height and depth with + */ + template BoundingVolume& BoundingVolume::operator*=(T scalar) { @@ -210,6 +395,13 @@ namespace Nz return *this; } + /*! + * \brief Compares the bounding volume to other one + * \return true if the two bounding volumes are the same + * + * \param volume Other bounding volume to compare with + */ + template bool BoundingVolume::operator==(const BoundingVolume& volume) const { @@ -222,12 +414,26 @@ namespace Nz return false; } + /*! + * \brief Compares the bounding volume to other one + * \return false if the two bounding volumes are the same + * + * \param volume Other bounding volume to compare with + */ + template bool BoundingVolume::operator!=(const BoundingVolume& volume) const { return !operator==(volume); } + /*! + * \brief Shorthand for the bounding volume (Extend_Infinite) + * \return A bounding volume with Extend_Infinite + * + * \see MakeInfinite + */ + template BoundingVolume BoundingVolume::Infinite() { @@ -237,6 +443,21 @@ namespace Nz return volume; } + /*! + * \brief Interpolates the bounding volume to other one with a factor of interpolation + * \return A new bounding volume box which is the interpolation of two bounding volumes + * + * \param from Initial bounding volume + * \param to Target bounding volume + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Null() is returned + * \remark If enumeration is not defined in Extend, a NazaraError is thrown and Null() is returned + * + * \see Lerp + */ + template BoundingVolume BoundingVolume::Lerp(const BoundingVolume& from, const BoundingVolume& to, T interpolation) { @@ -275,13 +496,13 @@ namespace Nz return from.obb * interpolation; } - // Si nous arrivons ici c'est que l'extend est invalide + // If we arrive here, the extend is invalid NazaraError("Invalid extend type (From) (0x" + String::Number(from.extend, 16) + ')'); return Null(); } case Extend_Infinite: - return Infinite(); // Un petit peu d'infini est infini quand même ;) + return Infinite(); // A little bit of infinity is already too much ;) case Extend_Null: { @@ -297,17 +518,24 @@ namespace Nz return Null(); } - // Si nous arrivons ici c'est que l'extend est invalide + // If we arrive here, the extend is invalid NazaraError("Invalid extend type (From) (0x" + String::Number(from.extend, 16) + ')'); return Null(); } } - // Si nous arrivons ici c'est que l'extend est invalide + // If we arrive here, the extend is invalid NazaraError("Invalid extend type (To) (0x" + String::Number(to.extend, 16) + ')'); return Null(); } + /*! + * \brief Shorthand for the bounding volume (Extend_Null) + * \return A bounding volume with Extend_Null + * + * \see MakeNull + */ + template BoundingVolume BoundingVolume::Null() { @@ -316,13 +544,21 @@ namespace Nz return volume; } - - template - std::ostream& operator<<(std::ostream& out, const BoundingVolume& volume) - { - out << volume.ToString(); - return out; } + +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param volume The bounding volume to output +*/ + +template +std::ostream& operator<<(std::ostream& out, const Nz::BoundingVolume& volume) +{ + out << volume.ToString(); + return out; } #undef F diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index 158d7753c..d8de5bdab 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -40,8 +40,8 @@ namespace Nz Box& ExtendTo(const Vector3& point); Sphere GetBoundingSphere() const; - Vector3 GetCorner(BoxCorner corner) const; Vector3 GetCenter() const; + Vector3 GetCorner(BoxCorner corner) const; Vector3 GetLengths() const; Vector3 GetMaximum() const; Vector3 GetMinimum() const; diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index a39f867da..a377b7d8f 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -12,41 +12,103 @@ namespace Nz { + /*! + * \class Nz::Box + * \brief Math class that represents a three dimensional box + */ + + /*! + * \brief Constructs a Box object from its width, height and depth + * + * \param Width Width of the box (following X) + * \param Height Height of the box (following Y) + * \param Depth Depth of the box (following Z) + * + * \remark Position will be (0, 0, 0) + */ + template Box::Box(T Width, T Height, T Depth) { Set(Width, Height, Depth); } + /*! + * \brief Constructs a Rect object from its position, width, height and depth + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Width Width of the box (following X) + * \param Height Height of the box (following Y) + * \param Depth Depth of the box (following Z) + */ + template Box::Box(T X, T Y, T Z, T Width, T Height, T Depth) { Set(X, Y, Z, Width, Height, Depth); } + /*! + * \brief Constructs a Box object from an array of six elements + * + * \param vec[6] vec[0] is X position, vec[1] is Y position, vec[2] is Z position, vec[3] is width, vec[4] is height and vec[5] is depth + */ + + template + Box::Box(const T vec[6]) + { + Set(vec); + } + + /*! + * \brief Constructs a Box object from a Rect + * + * \param rect Rectangle which describes (X, Y) position and (width, height) lenghts + * + * \remark Z position is 0 and depth is 1 + */ + template Box::Box(const Rect& rect) { Set(rect); } + /*! + * \brief Constructs a Box object from a vector representing width, height and depth + * + * \param lengths (Width, Height, Depth) of the box + * + * \remark Positions will be (0, 0, 0) + */ + template Box::Box(const Vector3& lengths) { Set(lengths); } + /*! + * \brief Constructs a Box object from two vectors representing point of the space + * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum + * + * \param vec1 First point + * \param vec2 Second point + */ + template Box::Box(const Vector3& vec1, const Vector3& vec2) { Set(vec1, vec2); } - template - Box::Box(const T vec[6]) - { - Set(vec); - } + /*! + * \brief Constructs a Box object from another type of Box + * + * \param box Box of type U to convert to type T + */ template template @@ -55,27 +117,67 @@ namespace Nz Set(box); } + /*! + * \brief Tests whether the box contains the provided point inclusive of the edge of the box + * \return true if inclusive + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see Contains + */ + template bool Box::Contains(T X, T Y, T Z) const { - return X >= x && X <= x+width && - Y >= y && Y <= y+height && - Z >= z && Z <= z+depth; + return X >= x && X <= x + width && + Y >= y && Y <= y + height && + Z >= z && Z <= z + depth; } + /*! + * \brief Tests whether the box contains the provided box inclusive of the edge of the box + * \return true if inclusive + * + * \param box Other box to test + * + * \see Contains + */ + template bool Box::Contains(const Box& box) const { return Contains(box.x, box.y, box.z) && - Contains(box.x + box.width, box.y + box.height, box.z + box.depth); + Contains(box.x + box.width, box.y + box.height, box.z + box.depth); } + /*! + * \brief Tests whether the box contains the provided point inclusive of the edge of the box + * \return true if inclusive + * + * \param point Position of the point + * + * \see Contains + */ + template bool Box::Contains(const Vector3& point) const { return Contains(point.x, point.y, point.z); } + /*! + * \brief Extends the box to contain the point in the boundary + * \return A reference to this box extended + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see ExtendTo + */ + template Box& Box::ExtendTo(T X, T Y, T Z) { @@ -94,6 +196,15 @@ namespace Nz return *this; } + /*! + * \brief Extends the box to contain the box + * \return A reference to this box extended + * + * \param box Other box to contain + * + * \see ExtendTo + */ + template Box& Box::ExtendTo(const Box& box) { @@ -112,12 +223,54 @@ namespace Nz return *this; } + /*! + * \brief Extends the box to contain the point in the boundary + * \return A reference to this box extended + * + * \param point Position of the point + * + * \see ExtendTo + */ + template Box& Box::ExtendTo(const Vector3& point) { return ExtendTo(point.x, point.y, point.z); } + /*! + * \brief Gets the bounding sphere for the box + * \return A sphere containing the box + * + * \see GetSquaredBoundingSphere + */ + + template + Sphere Box::GetBoundingSphere() const + { + return Sphere(GetCenter(), GetRadius()); + } + + /*! + * \brief Gets a Vector3 for the center + * \return The position of the center of the box + */ + + template + Vector3 Box::GetCenter() const + { + return GetPosition() + GetLengths() / F(2.0); + } + + /*! + * \brief Gets the Vector3 for the corner + * \return The position of the corner of the box according to enum BoxCorner + * + * \param corner Enumeration of type BoxCorner + * + * \remark If enumeration is not defined in BoxCorner, a NazaraError is thrown and a Vector3 uninitialised is returned + */ + template Vector3 Box::GetCorner(BoxCorner corner) const { @@ -152,17 +305,10 @@ namespace Nz return Vector3(); } - template - Sphere Box::GetBoundingSphere() const - { - return Sphere(GetCenter(), GetRadius()); - } - - template - Vector3 Box::GetCenter() const - { - return GetPosition() + GetLengths()/F(2.0); - } + /*! + * \brief Gets a Vector3 for the lengths + * \return The lengths of the box (width, height, depth) + */ template Vector3 Box::GetLengths() const @@ -170,19 +316,41 @@ namespace Nz return Vector3(width, height, depth); } + /*! + * \brief Gets a Vector3 for the maximum point + * \return The BoxCorner_NearRightTop of the box + * + * \see GetCorner + */ + template Vector3 Box::GetMaximum() const { return GetPosition() + GetLengths(); } + /*! + * \brief Gets a Vector3 for the minimum point + * \return The BoxCorner_FarLeftBottom of the box + * + * \see GetCorner, GetPosition + */ + template Vector3 Box::GetMinimum() const { - ///DOC: Alias de GetPosition() return GetPosition(); } + /*! + * \brief Computes the negative vertex of one direction + * \return The position of the vertex on the box in the opposite way of the normal while considering the center. It means that if the normal has one component negative, the component is set to width, height or depth corresponding to the sign + * + * \param normal Vector indicating a direction + * + * \see GetPositiveVertex + */ + template Vector3 Box::GetNegativeVertex(const Vector3& normal) const { @@ -200,12 +368,28 @@ namespace Nz return neg; } + /*! + * \brief Gets a Vector3 for the position + * \return The BoxCorner_FarLeftBottom of the box + * + * \see GetCorner, GetMinimum + */ + template Vector3 Box::GetPosition() const { return Vector3(x, y, z); } + /*! + * \brief Computes the positive vertex of one direction + * \return The position of the vertex on the box in the same way of the normal while considering the center. It means that if the normal has one component positive, the component is set to width or height corresponding to the sign + * + * \param normal Vector indicating a direction + * + * \see GetNegativeVertex + */ + template Vector3 Box::GetPositiveVertex(const Vector3& normal) const { @@ -223,27 +407,52 @@ namespace Nz return pos; } + /*! + * \brief Gets the radius of the box + * \return Value of the radius which is the biggest distance between a corner and the center + */ + template T Box::GetRadius() const { return std::sqrt(GetSquaredRadius()); } + /*! + * \brief Gets the squared bounding sphere for the box + * \return A sphere containing the box + * + * \see GetBoundingSphere + */ + template Sphere Box::GetSquaredBoundingSphere() const { return Sphere(GetCenter(), GetSquaredRadius()); } + /*! + * \brief Gets the squared radius of the box + * \return Value of the squared radius which is the squared of biggest distance between a corner and the center + */ + template T Box::GetSquaredRadius() const { Vector3 size(GetLengths()); - size /= F(2.0); // La taille étant relative à la position (minimum) de la boite et non pas à son centre + size /= F(2.0); // The size only depends on the lengths and not the center return size.GetSquaredLength(); } + /*! + * \brief Checks whether or not this box intersects another one + * \return true if the box intersects + * + * \param box Box to check + * \param intersection Optional argument for the box which represent the intersection + */ + template bool Box::Intersect(const Box& box, Box* intersection) const { @@ -275,12 +484,24 @@ namespace Nz return true; } + /*! + * \brief Checks whether this box is valid + * \return true if the box has a strictly positive width, height and depth + */ + template bool Box::IsValid() const { return width > F(0.0) && height > F(0.0) && depth > F(0.0); } + /*! + * \brief Makes the box position (0, 0, 0) and lengths (0, 0, 0) + * \return A reference to this box with position (0, 0, 0) and lengths (0, 0, 0) + * + * \see Zero + */ + template Box& Box::MakeZero() { @@ -294,6 +515,17 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the box with width, height and depth + * \return A reference to this box + * + * \param Width Width of the box (following X) + * \param Height Height of the box (following Y) + * \param Depth Depth of the box (following Z) + * + * \remark Position will be (0, 0, 0) + */ + template Box& Box::Set(T Width, T Height, T Depth) { @@ -307,6 +539,17 @@ namespace Nz return *this; } + /*! + * \brief Constructs a Box object from its position and sizes + * + * \param X X component of position + * \param Y Y component of position + * \param Z Z component of position + * \param Width Width of the box (following X) + * \param Height Height of the box (following Y) + * \param Depth Depth of the box (following Z) + */ + template Box& Box::Set(T X, T Y, T Z, T Width, T Height, T Depth) { @@ -320,6 +563,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the box from an array of six elements + * \return A reference to this box + * + * \param box[6] box[0] is X position, box[1] is Y position, box[2] is Z position, box[3] is width, box[4] is height and box[5] is depth + */ + template Box& Box::Set(const T box[6]) { @@ -333,6 +583,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the box with components from another + * \return A reference to this box + * + * \param box The other box + */ + template Box& Box::Set(const Box& box) { @@ -341,6 +598,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the box with components from a Rect + * \return A reference to this box + * + * \param rect Rectangle which describes (X, Y) position and (width, height) lenghts + * + * \remark Z position is 0 and depth is 1 + */ + template Box& Box::Set(const Rect& rect) { @@ -354,25 +620,50 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the box from a vector representing width, height and depth + * \return A reference to this box + * + * \param lengths (Width, Height, depth) of the box + * + * \remark Position will be (0, 0, 0) + */ + template Box& Box::Set(const Vector3& lengths) { return Set(lengths.x, lengths.y, lengths.z); } + /*! + * \brief Sets the components of the box from two vectors representing point of the space + * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum + * \return A reference to this box + * + * \param vec1 First point + * \param vec2 Second point + */ + template Box& Box::Set(const Vector3& vec1, const Vector3& vec2) { x = std::min(vec1.x, vec2.x); y = std::min(vec1.y, vec2.y); z = std::min(vec1.z, vec2.z); - width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x; - height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y; - depth = (vec2.z > vec1.z) ? vec2.z-vec1.z : vec1.z-vec2.z; + width = (vec2.x > vec1.x) ? vec2.x - vec1.x : vec1.x - vec2.x; + height = (vec2.y > vec1.y) ? vec2.y - vec1.y : vec1.y - vec2.y; + depth = (vec2.z > vec1.z) ? vec2.z - vec1.z : vec1.z - vec2.z; return *this; } + /*! + * \brief Sets the components of the box from another type of Box + * \return A reference to this box + * + * \param box Box of type U to convert its components + */ + template template Box& Box::Set(const Box& box) @@ -387,6 +678,11 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Box(x, y, z, width, height, depth)" + */ + template String Box::ToString() const { @@ -395,19 +691,34 @@ namespace Nz return ss << "Box(" << x << ", " << y << ", " << z << ", " << width << ", " << height << ", " << depth << ')'; } + /*! + * \brief Transforms the box according to the matrix + * \return A reference to this box transformed + * + * \param matrix Matrix4 representing the transformation + * \param applyTranslation Should transform the position or the direction + */ + template Box& Box::Transform(const Matrix4& matrix, bool applyTranslation) { - Vector3 center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation - Vector3 halfSize = GetLengths()/F(2.0); + Vector3 center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Value multiplying the translation + Vector3 halfSize = GetLengths() / F(2.0); - halfSize.Set(std::abs(matrix(0,0))*halfSize.x + std::abs(matrix(1,0))*halfSize.y + std::abs(matrix(2,0))*halfSize.z, - std::abs(matrix(0,1))*halfSize.x + std::abs(matrix(1,1))*halfSize.y + std::abs(matrix(2,1))*halfSize.z, - std::abs(matrix(0,2))*halfSize.x + std::abs(matrix(1,2))*halfSize.y + std::abs(matrix(2,2))*halfSize.z); + halfSize.Set(std::abs(matrix(0,0)) * halfSize.x + std::abs(matrix(1,0)) * halfSize.y + std::abs(matrix(2,0)) * halfSize.z, + std::abs(matrix(0,1)) * halfSize.x + std::abs(matrix(1,1)) * halfSize.y + std::abs(matrix(2,1)) * halfSize.z, + std::abs(matrix(0,2)) * halfSize.x + std::abs(matrix(1,2)) * halfSize.y + std::abs(matrix(2,2)) * halfSize.z); return Set(center - halfSize, center + halfSize); } + /*! + * \brief Translates the box + * \return A reference to this box translated + * + * \param translation Vector3 which is the translation for the position + */ + template Box& Box::Translate(const Vector3& translation) { @@ -418,6 +729,15 @@ namespace Nz return *this; } + /*! + * \brief Returns the ith element of the box + * \return A reference to the ith element of the box + * + * \remark Access to index greather than 6 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 6 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 6 + */ + template T& Box::operator[](unsigned int i) { @@ -435,6 +755,15 @@ namespace Nz return *(&x+i); } + /*! + * \brief Returns the ith element of the box + * \return A value to the ith element of the box + * + * \remark Access to index greather than 6 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 6 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 6 + */ + template T Box::operator[](unsigned int i) const { @@ -452,18 +781,39 @@ namespace Nz return *(&x+i); } + /*! + * \brief Multiplies the lengths with the scalar + * \return A box where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar + * + * \param scale The scalar to multiply width, height and depth with + */ + template Box Box::operator*(T scalar) const { - return Box(x, y, z, width*scalar, height*scalar, depth*scalar); + return Box(x, y, z, width * scalar, height * scalar, depth * scalar); } + /*! + * \brief Multiplies the lengths with the vector + * \return A box where the position is the same and width, height and depth are the product of the old width, height and depth with the vec + * + * \param vec The vector where component one multiply width, two height and three depth + */ + template Box Box::operator*(const Vector3& vec) const { - return Box(x, y, z, width*vec.x, height*vec.y, depth*vec.z); + return Box(x, y, z, width * vec.x, height * vec.y, depth * vec.z); } + /*! + * \brief Multiplies the lengths of this box with the scalar + * \return A reference to this box where lengths are the product of these lengths and the scalar + * + * \param scalar The scalar to multiply width, height and depth with + */ + template Box& Box::operator*=(T scalar) { @@ -474,6 +824,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the lengths of this box with the vector + * \return A reference to this box where width, height and depth are the product of the old width, height and depth with the vec + * + * \param vec The vector where component one multiply width, two height and three depth + */ + template Box& Box::operator*=(const Vector3& vec) { @@ -484,19 +841,47 @@ namespace Nz return *this; } + /*! + * \brief Compares the box to other one + * \return true if the boxes are the same + * + * \param box Other box to compare with + */ + template bool Box::operator==(const Box& box) const { return NumberEquals(x, box.x) && NumberEquals(y, box.y) && NumberEquals(z, box.z) && - NumberEquals(width, box.width) && NumberEquals(height, box.height) && NumberEquals(depth, box.depth); + NumberEquals(width, box.width) && NumberEquals(height, box.height) && NumberEquals(depth, box.depth); } + /*! + * \brief Compares the box to other one + * \return false if the boxes are the same + * + * \param box Other box to compare with + */ + template bool Box::operator!=(const Box& box) const { return !operator==(box); } + /*! + * \brief Interpolates the box to other one with a factor of interpolation + * \return A new box which is the interpolation of two rectangles + * + * \param from Initial box + * \param to Target box + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp + */ + template Box Box::Lerp(const Box& from, const Box& to, T interpolation) { @@ -519,6 +904,13 @@ namespace Nz return box; } + /*! + * \brief Shorthand for the box (0, 0, 0, 0, 0, 0) + * \return A box with position (0, 0, 0) and lengths (0, 0, 0) + * + * \see MakeZero + */ + template Box Box::Zero() { @@ -529,6 +921,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param box The box to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Box& box) { From 5d0624f03fbe90d01d0a1957f313ba213afc4b3a Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:30:13 +0100 Subject: [PATCH 030/229] Documentation for EulerAngles + change Return of Set Former-commit-id: 7e269b89e880156d66d92cff202095c4e30f344d --- include/Nazara/Math/Config.hpp | 8 +- include/Nazara/Math/EulerAngles.hpp | 14 +- include/Nazara/Math/EulerAngles.inl | 196 +++++++++++++++++++++++++--- 3 files changed, 191 insertions(+), 27 deletions(-) diff --git a/include/Nazara/Math/Config.hpp b/include/Nazara/Math/Config.hpp index f265fdd52..3d27848af 100644 --- a/include/Nazara/Math/Config.hpp +++ b/include/Nazara/Math/Config.hpp @@ -28,15 +28,15 @@ #ifndef NAZARA_CONFIG_MATH_HPP #define NAZARA_CONFIG_MATH_HPP -/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +/// Each modification of a paramater of the module needs a recompilation of the unit -// Définit le radian comme l'unité utilisée pour les angles +// Define the radian as unit for angles #define NAZARA_MATH_ANGLE_RADIAN 0 -// Optimise automatiquement les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine) +// Optimize automatically the operation on affine matrices (Ask several comparisons to determine if the matrix is affine) #define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0 -// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +// Enable tests of security based on the code (Advised for the developpement) #define NAZARA_MATH_SAFE 1 #endif // NAZARA_CONFIG_MATH_HPP diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index d323fe641..3c9a6b684 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -28,14 +28,14 @@ namespace Nz void MakeZero(); - void Normalize(); + EulerAngles& Normalize(); - void Set(T P, T Y, T R); - void Set(const T angles[3]); - void Set(const EulerAngles& angles); - //void Set(const Matrix3& mat); - void Set(const Quaternion& quat); - template void Set(const EulerAngles& angles); + EulerAngles& Set(T P, T Y, T R); + EulerAngles& Set(const T angles[3]); + EulerAngles& Set(const EulerAngles& angles); + //EulerAngles& Set(const Matrix3& mat); + EulerAngles& Set(const Quaternion& quat); + template EulerAngles& Set(const EulerAngles& angles); //Matrix3 ToRotationMatrix() const; Quaternion ToQuaternion() const; diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index 79e3c1ded..3e4eabc6a 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -14,24 +14,58 @@ namespace Nz { + + /*! + * \class Nz::Vector4 + * \brief Math class that represents an Euler angle. Those describe a rotation transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order + * + * \remark Rotation are "left-handed", it means that you take your left hand, put your thumb finger in the direction you want and you other fingers represent the way of rotating + */ + + /*! + * \brief Constructs a EulerAngles object from its components + * + * \param P Pitch component = X axis + * \param Y Yaw component = Y axis + * \param R Roll component = Z axis + */ + template EulerAngles::EulerAngles(T P, T Y, T R) { Set(P, Y, R); } + /*! + * \brief Constructs a EulerAngles object from an array of three elements + * + * \param angles[3] angles[0] is pitch component, angles[1] is yaw component and angles[2] is roll component + */ + template EulerAngles::EulerAngles(const T angles[3]) { Set(angles); } + /*! + * \brief Constructs a EulerAngles object from a quaternion + * + * \param quat Quaternion representing a rotation of space + */ + template EulerAngles::EulerAngles(const Quaternion& quat) { Set(quat); } + /*! + * \brief Constructs a EulerAngles object from another type of EulerAngles + * + * \param angles EulerAngles of type U to convert to type T + */ + template template EulerAngles::EulerAngles(const EulerAngles& angles) @@ -39,57 +73,125 @@ namespace Nz Set(angles); } + /*! + * \brief Makes the euler angle (0, 0, 0) + * \return A reference to this euler angle with components (0, 0, 0) + * + * \see Zero + */ + template void EulerAngles::MakeZero() { Set(F(0.0), F(0.0), F(0.0)); } + /*! + * \brief Normalizes the euler angle + * \return A reference to this euler angle with has been normalized + * + * \remark Normalization depends on NAZARA_MATH_ANGLE_RADIAN, between 0..2*pi + * + * \see NormalizeAngle + */ + template - void EulerAngles::Normalize() + EulerAngles& EulerAngles::Normalize() { pitch = NormalizeAngle(pitch); yaw = NormalizeAngle(yaw); roll = NormalizeAngle(roll); + + return *this; } + /*! + * \brief Sets the components of the euler angle + * \return A reference to this euler angle + * + * \param P Pitch component = X axis + * \param Y Yaw component = Y axis + * \param R Roll component = Z axis + */ + template - void EulerAngles::Set(T P, T Y, T R) + EulerAngles& EulerAngles::Set(T P, T Y, T R) { pitch = P; yaw = Y; roll = R; + + return *this; } + /*! + * \brief Sets the components of the euler angle from an array of three elements + * \return A reference to this euler angle + * + * \param angles[3] angles[0] is pitch component, angles[1] is yaw component and angles[2] is roll component + */ + template - void EulerAngles::Set(const T angles[3]) + EulerAngles& EulerAngles::Set(const T angles[3]) { pitch = angles[0]; yaw = angles[1]; roll = angles[2]; + + return *this; } + /*! + * \brief Sets the components of the euler angle from another euler angle + * \return A reference to this euler angle + * + * \param angles The other euler angle + */ + template - void EulerAngles::Set(const EulerAngles& angles) + EulerAngles& EulerAngles::Set(const EulerAngles& angles) { std::memcpy(this, &angles, sizeof(EulerAngles)); + + return *this; } + /*! + * \brief Sets the components of the euler angle from a quaternion + * \return A reference to this euler angle + * + * \param quat Quaternion representing a rotation of space + */ + template - void EulerAngles::Set(const Quaternion& quat) + EulerAngles& EulerAngles::Set(const Quaternion& quat) { - Set(quat.ToEulerAngles()); + return Set(quat.ToEulerAngles()); } + /*! + * \brief Sets the components of the euler angle from another type of EulerAngles + * \return A reference to this euler angle + * + * \param angles EulerAngles of type U to convert its components + */ + template template - void EulerAngles::Set(const EulerAngles& angles) + EulerAngles& EulerAngles::Set(const EulerAngles& angles) { pitch = F(angles.pitch); yaw = F(angles.yaw); roll = F(angles.roll); + + return *this; } + /*! + * \brief Converts the euler angle to quaternion + * \return A Quaternion which represents the rotation of this euler angle + */ + template Quaternion EulerAngles::ToQuaternion() const { @@ -102,11 +204,16 @@ namespace Nz T s3 = std::sin(ToRadians(pitch) / F(2.0)); return Quaternion(c1 * c2 * c3 - s1 * s2 * s3, - s1 * s2 * c3 + c1 * c2 * s3, - s1 * c2 * c3 + c1 * s2 * s3, - c1 * s2 * c3 - s1 * c2 * s3); + s1 * s2 * c3 + c1 * c2 * s3, + s1 * c2 * c3 + c1 * s2 * s3, + c1 * s2 * c3 - s1 * c2 * s3); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "EulerAngles(pitch, yaw, roll)" + */ + template String EulerAngles::ToString() const { @@ -115,22 +222,43 @@ namespace Nz return ss << "EulerAngles(" << pitch << ", " << yaw << ", " << roll << ')'; } + /*! + * \brief Adds the components of the euler angle with other euler angle + * \return A euler angle where components are the sum of this euler angle and the other one + * + * \param angles The other euler angle to add components with + */ + template EulerAngles EulerAngles::operator+(const EulerAngles& angles) const { return EulerAngles(pitch + angles.pitch, - yaw + angles.yaw, - roll + angles.roll); + yaw + angles.yaw, + roll + angles.roll); } + /*! + * \brief Substracts the components of the euler angle with other euler angle + * \return A euler angle where components are the difference of this euler angle and the other one + * + * \param angles The other euler angle to substract components with + */ + template EulerAngles EulerAngles::operator-(const EulerAngles& angles) const { return EulerAngles(pitch - angles.pitch, - yaw - angles.yaw, - roll - angles.roll); + yaw - angles.yaw, + roll - angles.roll); } + /*! + * \brief Adds the components of other euler angle to this euler angle + * \return A reference to this euler angle where components are the sum of this euler angle and the other one + * + * \param angles The other euler angle to add components with + */ + template EulerAngles& EulerAngles::operator+=(const EulerAngles& angles) { @@ -141,6 +269,13 @@ namespace Nz return *this; } + /*! + * \brief Substracts the components of other euler angle to this euler angle + * \return A reference to this euler angle where components are the difference of this euler angle and the other one + * + * \param angle The other euler angle to substract components with + */ + template EulerAngles& EulerAngles::operator-=(const EulerAngles& angles) { @@ -151,20 +286,41 @@ namespace Nz return *this; } + /*! + * \brief Compares the euler angle to other one + * \return true if the euler angles are the same + * + * \param angles Other euler angle to compare with + */ + template bool EulerAngles::operator==(const EulerAngles& angles) const { return NumberEquals(pitch, angles.pitch) && - NumberEquals(yaw, angles.yaw) && - NumberEquals(roll, angles.roll); + NumberEquals(yaw, angles.yaw) && + NumberEquals(roll, angles.roll); } + /*! + * \brief Compares the euler angle to other one + * \return false if the euler angles are the same + * + * \param angles Other euler angle to compare with + */ + template bool EulerAngles::operator!=(const EulerAngles& angles) const { return !operator==(angles); } + /*! + * \brief Shorthand for the euler angle (0, 0, 0) + * \return A euler angle with components (0, 0, 0) + * + * \see MakeZero + */ + template EulerAngles EulerAngles::Zero() { @@ -175,6 +331,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param angles The euler angle to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::EulerAngles& angles) { From fa48b750ae177b41674b0b988fe3f6871650c46f Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:31:27 +0100 Subject: [PATCH 031/229] Documentation for Frustum Former-commit-id: 38c09bfa36e663a77ebeb19f5b2c16f60f99ea14 --- include/Nazara/Math/Frustum.inl | 238 ++++++++++++++++++++++++++++---- 1 file changed, 209 insertions(+), 29 deletions(-) diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index e5bc2081b..35e63ca98 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -15,6 +15,20 @@ namespace Nz { + + /*! + * \class Nz::Frustum + * \brief Math class that represents a frustum in the three dimensional vector space + * + * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process + */ + + /*! + * \brief Constructs a Frustum object from another type of Frustum + * + * \param frustum Frustum of type U to convert to type T + */ + template template Frustum::Frustum(const Frustum& frustum) @@ -22,6 +36,19 @@ namespace Nz Set(frustum); } + /*! + * \brief Builds the frustum object + * \return A reference to this frustum which is the build up camera's field of view + * + * \param angle Unit depends on NAZARA_MATH_ANGLE_RADIAN + * \param ratio Rendering ratio (typically 16/9 or 4/3) + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * \param eye Position of the camera + * \param target Position of the target of the camera + * \param up Direction of up vector according to the orientation of camera + */ + template Frustum& Frustum::Build(T angle, T ratio, T zNear, T zFar, const Vector3& eye, const Vector3& target, const Vector3& up) { @@ -45,18 +72,18 @@ namespace Nz Vector3 nc = eye + f * zNear; Vector3 fc = eye + f * zFar; - // Calcul du frustum - m_corners[BoxCorner_FarLeftBottom] = fc - u*farH - s*farW; - m_corners[BoxCorner_FarLeftTop] = fc + u*farH - s*farW; - m_corners[BoxCorner_FarRightTop] = fc + u*farH + s*farW; - m_corners[BoxCorner_FarRightBottom] = fc - u*farH + s*farW; + // Computing the frustum + m_corners[BoxCorner_FarLeftBottom] = fc - u * farH - s * farW; + m_corners[BoxCorner_FarLeftTop] = fc + u * farH - s * farW; + m_corners[BoxCorner_FarRightTop] = fc + u * farH + s * farW; + m_corners[BoxCorner_FarRightBottom] = fc - u * farH + s * farW; - m_corners[BoxCorner_NearLeftBottom] = nc - u*nearH - s*nearW; - m_corners[BoxCorner_NearLeftTop] = nc + u*nearH - s*nearW; - m_corners[BoxCorner_NearRightTop] = nc + u*nearH + s*nearW; - m_corners[BoxCorner_NearRightBottom] = nc - u*nearH + s*nearW; + m_corners[BoxCorner_NearLeftBottom] = nc - u * nearH - s * nearW; + m_corners[BoxCorner_NearLeftTop] = nc + u * nearH - s * nearW; + m_corners[BoxCorner_NearRightTop] = nc + u * nearH + s * nearW; + m_corners[BoxCorner_NearRightBottom] = nc - u * nearH + s * nearW; - // Construction des plans du frustum + // Construction of frustum's planes m_planes[FrustumPlane_Bottom].Set(m_corners[BoxCorner_NearLeftBottom], m_corners[BoxCorner_NearRightBottom], m_corners[BoxCorner_FarRightBottom]); m_planes[FrustumPlane_Far].Set(m_corners[BoxCorner_FarRightTop], m_corners[BoxCorner_FarLeftTop], m_corners[BoxCorner_FarLeftBottom]); m_planes[FrustumPlane_Left].Set(m_corners[BoxCorner_NearLeftTop], m_corners[BoxCorner_NearLeftBottom], m_corners[BoxCorner_FarLeftBottom]); @@ -67,6 +94,18 @@ namespace Nz return *this; } + /*! + * \brief Checks whether or not a bounding volume is contained in the frustum + * \return true if the bounding volume is entirely in the frustum + * + * \param volume Volume to check + * + * \remark If volume is infinite, true is returned + * \remark If volume is null, false is returned + * \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned + * \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library + */ + template bool Frustum::Contains(const BoundingVolume& volume) const { @@ -102,11 +141,18 @@ namespace Nz return false; } + /*! + * \brief Checks whether or not a box is contained in the frustum + * \return true if the box is entirely in the frustum + * + * \param box Box to check + */ + template bool Frustum::Contains(const Box& box) const { // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ - for(unsigned int i = 0; i <= FrustumPlane_Max; i++) + for (unsigned int i = 0; i <= FrustumPlane_Max; i++) { if (m_planes[i].Distance(box.GetPositiveVertex(m_planes[i].normal)) < F(0.0)) return false; @@ -115,16 +161,30 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not an oriented box is contained in the frustum + * \return true if the oriented box is entirely in the frustum + * + * \param orientedbox Oriented box to check + */ + template bool Frustum::Contains(const OrientedBox& orientedbox) const { return Contains(&orientedbox[0], 8); } + /*! + * \brief Checks whether or not a sphere is contained in the frustum + * \return true if the sphere is entirely in the frustum + * + * \param sphere Sphere to check + */ + template bool Frustum::Contains(const Sphere& sphere) const { - for(unsigned int i = 0; i <= FrustumPlane_Max; i++) + for (unsigned int i = 0; i <= FrustumPlane_Max; i++) { if (m_planes[i].Distance(sphere.GetPosition()) < -sphere.radius) return false; @@ -133,10 +193,17 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not a Vector3 is contained in the frustum + * \return true if the Vector3 is in the frustum + * + * \param point Vector3 which represents a point in the space + */ + template bool Frustum::Contains(const Vector3& point) const { - for(unsigned int i = 0; i <= FrustumPlane_Max; ++i) + for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) { if (m_planes[i].Distance(point) < F(0.0)) return false; @@ -145,6 +212,14 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not a set of Vector3 is contained in the frustum + * \return true if the set of Vector3 is in the frustum + * + * \param points Pointer to Vector3 which represents a set of points in the space + * \param pointCount Number of points to check + */ + template bool Frustum::Contains(const Vector3* points, unsigned int pointCount) const { @@ -164,6 +239,15 @@ namespace Nz return true; } + /*! + * \brief Constructs the frustum from a Matrix4 + * \return A reference to this frustum which is the build up of projective matrix + * + * \param clipMatrix Matrix which represents the transformation of the frustum + * + * \remark A NazaraWarning is produced if clipMatrix is not inversible and corners are unchanged + */ + template Frustum& Frustum::Extract(const Matrix4& clipMatrix) { @@ -178,7 +262,7 @@ namespace Nz plane[3] = clipMatrix[15] - clipMatrix[12]; // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + invLength = F(1.0) / std::sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]); plane[0] *= invLength; plane[1] *= invLength; plane[2] *= invLength; @@ -193,7 +277,7 @@ namespace Nz plane[3] = clipMatrix[15] + clipMatrix[12]; // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + invLength = F(1.0) / std::sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]); plane[0] *= invLength; plane[1] *= invLength; plane[2] *= invLength; @@ -208,7 +292,7 @@ namespace Nz plane[3] = clipMatrix[15] + clipMatrix[13]; // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + invLength = F(1.0) / std::sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]); plane[0] *= invLength; plane[1] *= invLength; plane[2] *= invLength; @@ -223,7 +307,7 @@ namespace Nz plane[3] = clipMatrix[15] - clipMatrix[13]; // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + invLength = F(1.0) / std::sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]); plane[0] *= invLength; plane[1] *= invLength; plane[2] *= invLength; @@ -238,7 +322,7 @@ namespace Nz plane[3] = clipMatrix[15] - clipMatrix[14]; // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + invLength = F(1.0) / std::sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]); plane[0] *= invLength; plane[1] *= invLength; plane[2] *= invLength; @@ -253,7 +337,7 @@ namespace Nz plane[3] = clipMatrix[15] + clipMatrix[14]; // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + invLength = F(1.0) / std::sqrt(plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2]); plane[0] *= invLength; plane[1] *= invLength; plane[2] *= invLength; @@ -261,8 +345,8 @@ namespace Nz m_planes[FrustumPlane_Near].Set(plane); - // Une fois les plans extraits, il faut extraire les points du frustum - // Je me base sur cette page: http://www.gamedev.net/topic/393309-calculating-the-view-frustums-vertices/ + // Once planes have been extracted, we must extract points of the frustum + // Based on: http://www.gamedev.net/topic/393309-calculating-the-view-frustums-vertices/ Matrix4 invClipMatrix; if (clipMatrix.GetInverse(&invClipMatrix)) @@ -331,12 +415,31 @@ namespace Nz return *this; } + /*! + * \brief Constructs the frustum from the view matrix and the projection matrix + * \return A reference to this frustum which is the build up of projective matrix + * + * \param view Matrix which represents the view + * \param projection Matrix which represents the projection (the perspective) + * + * \remark A NazaraWarning is produced if the product of these matrices is not inversible and corners are unchanged + */ + template Frustum& Frustum::Extract(const Matrix4& view, const Matrix4& projection) { return Extract(Matrix4::Concatenate(view, projection)); } + /*! + * \brief Gets the Vector3 for the corner + * \return The position of the corner of the frustum according to enum BoxCorner + * + * \param corner Enumeration of type BoxCorner + * + * \remark If enumeration is not defined in BoxCorner and NAZARA_DEBUG defined, a NazaraError is thrown and a Vector3 uninitialised is returned + */ + template const Vector3& Frustum::GetCorner(BoxCorner corner) const { @@ -353,6 +456,15 @@ namespace Nz return m_corners[corner]; } + /*! + * \brief Gets the Plane for the face + * \return The face of the frustum according to enum FrustumPlane + * + * \param plane Enumeration of type FrustumPlane + * + * \remark If enumeration is not defined in FrustumPlane and NAZARA_DEBUG defined, a NazaraError is thrown and a Plane uninitialised is returned + */ + template const Plane& Frustum::GetPlane(FrustumPlane plane) const { @@ -369,6 +481,18 @@ namespace Nz return m_planes[plane]; } + /*! + * \brief Checks whether or not a bounding volume intersects with the frustum + * \return IntersectionSide How the bounding volume is intersecting with the frustum + * + * \param volume Volume to check + * + * \remark If volume is infinite, IntersectionSide_Intersecting is returned + * \remark If volume is null, IntersectionSide_Outside is returned + * \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned + * \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library + */ + template IntersectionSide Frustum::Intersect(const BoundingVolume& volume) const { @@ -394,7 +518,7 @@ namespace Nz } case Extend_Infinite: - return IntersectionSide_Intersecting; // On ne peut pas contenir l'infini + return IntersectionSide_Intersecting; // We can not contain infinity case Extend_Null: return IntersectionSide_Outside; @@ -404,13 +528,20 @@ namespace Nz return IntersectionSide_Outside; } + /*! + * \brief Checks whether or not a box intersects with the frustum + * \return IntersectionSide How the box is intersecting with the frustum + * + * \param box Box to check + */ + template IntersectionSide Frustum::Intersect(const Box& box) const { // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ IntersectionSide side = IntersectionSide_Inside; - for(unsigned int i = 0; i <= FrustumPlane_Max; i++) + for (unsigned int i = 0; i <= FrustumPlane_Max; i++) { if (m_planes[i].Distance(box.GetPositiveVertex(m_planes[i].normal)) < F(0.0)) return IntersectionSide_Outside; @@ -421,19 +552,33 @@ namespace Nz return side; } + /*! + * \brief Checks whether or not an oriented box intersects with the frustum + * \return IntersectionSide How the oriented box is intersecting with the frustum + * + * \param oriented box OrientedBox to check + */ + template IntersectionSide Frustum::Intersect(const OrientedBox& orientedbox) const { return Intersect(&orientedbox[0], 8); } + /*! + * \brief Checks whether or not a sphere intersects with the frustum + * \return IntersectionSide How the sphere is intersecting with the frustum + * + * \param sphere Sphere to check + */ + template IntersectionSide Frustum::Intersect(const Sphere& sphere) const { // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-points-and-spheres/ IntersectionSide side = IntersectionSide_Inside; - for(unsigned int i = 0; i <= FrustumPlane_Max; i++) + for (unsigned int i = 0; i <= FrustumPlane_Max; i++) { T distance = m_planes[i].Distance(sphere.GetPosition()); if (distance < -sphere.radius) @@ -445,6 +590,14 @@ namespace Nz return side; } + /*! + * \brief Checks whether or not a set of Vector3 intersects with the frustum + * \return IntersectionSide How the set of Vector3 is intersecting with the frustum + * + * \param points Pointer to Vector3 which represents a set of points in the space + * \param pointCount Number of points to check + */ + template IntersectionSide Frustum::Intersect(const Vector3* points, unsigned int pointCount) const { @@ -468,6 +621,13 @@ namespace Nz return (c == 6) ? IntersectionSide_Inside : IntersectionSide_Intersecting; } + /*! + * \brief Sets the components of the frustum from another frustum + * \return A reference to this frustum + * + * \param frustum The other frustum + */ + template Frustum& Frustum::Set(const Frustum& frustum) { @@ -476,6 +636,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the frustum from another type of Frustum + * \return A reference to this frustum + * + * \param frustum Frustum of type U to convert its components + */ + template template Frustum& Frustum::Set(const Frustum& frustum) @@ -489,20 +656,33 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Frustum(Plane ...)" + */ + template String Frustum::ToString() const { StringStream ss; return ss << "Frustum(Bottom: " << m_planes[FrustumPlane_Bottom].ToString() << "\n" - << " Far: " << m_planes[FrustumPlane_Far].ToString() << "\n" - << " Left: " << m_planes[FrustumPlane_Left].ToString() << "\n" - << " Near: " << m_planes[FrustumPlane_Near].ToString() << "\n" - << " Right: " << m_planes[FrustumPlane_Right].ToString() << "\n" - << " Top: " << m_planes[FrustumPlane_Top].ToString() << ")\n"; + << " Far: " << m_planes[FrustumPlane_Far].ToString() << "\n" + << " Left: " << m_planes[FrustumPlane_Left].ToString() << "\n" + << " Near: " << m_planes[FrustumPlane_Near].ToString() << "\n" + << " Right: " << m_planes[FrustumPlane_Right].ToString() << "\n" + << " Top: " << m_planes[FrustumPlane_Top].ToString() << ")\n"; } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param frustum The frustum to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Frustum& frustum) { From f131fd2121d02e85ba655c7f9f43a18e2297b827 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:32:09 +0100 Subject: [PATCH 032/229] Documentation for Matrix4 + Check for affine Former-commit-id: 9ddb4e85f860b12d06afaa2d32139bea4053eb66 --- include/Nazara/Math/Matrix4.hpp | 22 +- include/Nazara/Math/Matrix4.inl | 1131 +++++++++++++++++++++++++------ 2 files changed, 916 insertions(+), 237 deletions(-) diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index d72529d92..211e8eedb 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -26,9 +26,9 @@ namespace Nz public: Matrix4() = default; Matrix4(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44); + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44); //Matrix4(const Matrix3& matrix); Matrix4(const T matrix[16]); template explicit Matrix4(const Matrix4& matrix); @@ -77,9 +77,9 @@ namespace Nz Matrix4& MakeZero(); Matrix4& Set(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44); + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44); Matrix4& Set(const T matrix[16]); //Matrix4(const Matrix3& matrix); Matrix4& Set(const Matrix4& matrix); @@ -96,8 +96,8 @@ namespace Nz Matrix4& Transpose(); - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; T& operator()(unsigned int x, unsigned int y); T operator()(unsigned int x, unsigned int y) const; @@ -131,9 +131,9 @@ namespace Nz static Matrix4 Zero(); T m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44; + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44; }; typedef Matrix4 Matrix4d; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 834a3fb70..e2f604aed 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -20,24 +20,50 @@ namespace Nz { + + /*! + * \class Nz::Matrix4 + * \brief Math class that represents a transformation of the four dimensional vector space with the notion of projectivity + * + * \remark Matrix4 is said to be "row-major" and affine if last column is made of (0, 0, 0, 1) + */ + + /*! + * \brief Constructs a Matrix4 object from its components + * + * \param rIJ Matrix components at index(I, J) + */ + template Matrix4::Matrix4(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44) + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44) { Set(r11, r12, r13, r14, - r21, r22, r23, r24, - r31, r32, r33, r34, - r41, r42, r43, r44); + r21, r22, r23, r24, + r31, r32, r33, r34, + r41, r42, r43, r44); } + /*! + * \brief Constructs a Matrix4 object from an array of sixteen elements + * + * \param matrix[16] Matrix components + */ + template Matrix4::Matrix4(const T matrix[16]) { Set(matrix); } + /*! + * \brief Constructs a Matrix4 object from another type of Matrix4 + * + * \param matrix Matrix4 of type U to convert to type T + */ + template template Matrix4::Matrix4(const Matrix4& matrix) @@ -45,12 +71,26 @@ namespace Nz Set(matrix); } + /*! + * \brief Apply the rotation represented by the quaternion to this matrix + * \return A reference to this matrix which has been rotated + * + * \param rotation Quaternion representing a rotation of space + */ + template Matrix4& Matrix4::ApplyRotation(const Quaternion& rotation) { return Concatenate(Matrix4::Rotate(rotation)); } + /*! + * \brief Apply the scale represented by the vector to this matrix + * \return A reference to this matrix which has been scaled + * + * \param scale Vector3 representing the homothety + */ + template Matrix4& Matrix4::ApplyScale(const Vector3& scale) { @@ -69,6 +109,13 @@ namespace Nz return *this; } + /*! + * \brief Apply the translation represented by the vector to this matrix + * \return A reference to this matrix which has been translated + * + * \param translation Vector3 representing the translation + */ + template Matrix4& Matrix4::ApplyTranslation(const Vector3& translation) { @@ -79,6 +126,17 @@ namespace Nz return *this; } + /*! + * \brief Concatenates this matrix to other one + * \return A reference to this matrix which is the product with other one + * + * \param matrix Matrix to multiply with + * + * \remark if NAZARA_MATH_MATRIX4_CHECK_AFFINE is defined, ConcatenateAffine is called + * + * \see ConcatenateAffine + */ + template Matrix4& Matrix4::Concatenate(const Matrix4& matrix) { @@ -88,26 +146,37 @@ namespace Nz #endif return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31 + m14*matrix.m41, - m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42, - m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43, - m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44, + m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42, + m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43, + m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44, - m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41, - m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42, - m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43, - m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44, + m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41, + m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42, + m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43, + m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44, - m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41, - m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42, - m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43, - m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44, + m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41, + m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42, + m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43, + m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44, - m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41, - m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42, - m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43, - m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44); + m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41, + m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42, + m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43, + m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44); } + /*! + * \brief Concatenates this matrix to other one + * \return A reference to this matrix which is the product with other one + * + * \param matrix Matrix to multiply with + * + * \remark if NAZARA_DEBUG is defined and matrices are not affine, a NazaraWarning is produced and Concatenate is called + * + * \see Concatenate + */ + template Matrix4& Matrix4::ConcatenateAffine(const Matrix4& matrix) { @@ -126,26 +195,36 @@ namespace Nz #endif return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31, - m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32, - m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33, - F(0.0), + m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32, + m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33, + F(0.0), - m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31, - m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32, - m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33, - F(0.0), + m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31, + m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32, + m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33, + F(0.0), - m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31, - m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32, - m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33, - F(0.0), + m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31, + m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32, + m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33, + F(0.0), - m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + matrix.m41, - m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + matrix.m42, - m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + matrix.m43, - F(1.0)); + m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + matrix.m41, + m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + matrix.m42, + m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + matrix.m43, + F(1.0)); } + /*! + * \brief Gets the ith column of the matrix + * \return Vector4 which is the transformation of this axis + * + * \param column Index of the column you want + * + * \remark Produce a NazaraError if you try to access index greater than 3 with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 + */ + template Vector4 Matrix4::GetColumn(unsigned int column) const { @@ -154,10 +233,10 @@ namespace Nz #if NAZARA_MATH_SAFE if (column > 3) { - StringStream ss; - ss << "Row out of range: (" << column << ") > 3"; + String error("Column out of range: (" + String::Number(column) + ") > 3"); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif @@ -165,9 +244,23 @@ namespace Nz return Vector4(ptr); } + /*! + * \brief Calcultes the determinant of this matrix + * \return The value of the determinant + * + * \remark if NAZARA_MATH_MATRIX4_CHECK_AFFINE is defined, GetDeterminantAffine is called + * + * \see GetDeterminantAffine + */ + template T Matrix4::GetDeterminant() const { + #if NAZARA_MATH_MATRIX4_CHECK_AFFINE + if (IsAffine()) + return GetDeterminantAffine(); + #endif + T A = m22*(m33*m44 - m43*m34) - m32*(m23*m44 - m43*m24) + m42*(m23*m34 - m33*m24); T B = m12*(m33*m44 - m43*m34) - m32*(m13*m44 - m43*m14) + m42*(m13*m34 - m33*m14); T C = m12*(m23*m44 - m43*m24) - m22*(m13*m44 - m43*m14) + m42*(m13*m24 - m23*m14); @@ -176,9 +269,26 @@ namespace Nz return m11*A - m21*B + m31*C - m41*D; } + /*! + * \brief Calcultes the determinant of this matrix + * \return The value of the determinant + * + * \remark if NAZARA_DEBUG is defined and matrix is not affine, a NazaraWarning is produced and GetDeterminant is called + * + * \see GetDeterminant + */ + template T Matrix4::GetDeterminantAffine() const { + #ifdef NAZARA_DEBUG + if (!IsAffine()) + { + NazaraWarning("First matrix not affine"); + return GetDeterminant(); + } + #endif + T A = m22*m33 - m32*m23; T B = m12*m33 - m32*m13; T C = m12*m23 - m22*m13; @@ -186,10 +296,27 @@ namespace Nz return m11*A - m21*B + m31*C; } + /*! + * \brief Gets the inverse of this matrix + * \return true if matrix can be inverted + * + * \param dest Matrix to put the result + * + * \remark You can call this method on the same object + * \remark if NAZARA_MATH_MATRIX4_CHECK_AFFINE is defined, GetInverseAffine is called + * \remark if NAZARA_DEBUG is defined, a NazaraError is produced if dest is null and false is returned + * + * \see GetInverseAffine + */ + template bool Matrix4::GetInverse(Matrix4* dest) const { - ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant + #if NAZARA_MATH_MATRIX4_CHECK_AFFINE + if (IsAffine()) + return GetInverseAffine(dest); + #endif + #ifdef NAZARA_DEBUG if (!dest) { @@ -204,116 +331,116 @@ namespace Nz // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix T inv[16]; inv[0] = m22 * m33 * m44 - - m22 * m34 * m43 - - m32 * m23 * m44 + - m32 * m24 * m43 + - m42 * m23 * m34 - - m42 * m24 * m33; + m22 * m34 * m43 - + m32 * m23 * m44 + + m32 * m24 * m43 + + m42 * m23 * m34 - + m42 * m24 * m33; inv[1] = -m12 * m33 * m44 + - m12 * m34 * m43 + - m32 * m13 * m44 - - m32 * m14 * m43 - - m42 * m13 * m34 + - m42 * m14 * m33; + m12 * m34 * m43 + + m32 * m13 * m44 - + m32 * m14 * m43 - + m42 * m13 * m34 + + m42 * m14 * m33; inv[2] = m12 * m23 * m44 - - m12 * m24 * m43 - - m22 * m13 * m44 + - m22 * m14 * m43 + - m42 * m13 * m24 - - m42 * m14 * m23; + m12 * m24 * m43 - + m22 * m13 * m44 + + m22 * m14 * m43 + + m42 * m13 * m24 - + m42 * m14 * m23; inv[3] = -m12 * m23 * m34 + - m12 * m24 * m33 + - m22 * m13 * m34 - - m22 * m14 * m33 - - m32 * m13 * m24 + - m32 * m14 * m23; + m12 * m24 * m33 + + m22 * m13 * m34 - + m22 * m14 * m33 - + m32 * m13 * m24 + + m32 * m14 * m23; inv[4] = -m21 * m33 * m44 + - m21 * m34 * m43 + - m31 * m23 * m44 - - m31 * m24 * m43 - - m41 * m23 * m34 + - m41 * m24 * m33; + m21 * m34 * m43 + + m31 * m23 * m44 - + m31 * m24 * m43 - + m41 * m23 * m34 + + m41 * m24 * m33; inv[5] = m11 * m33 * m44 - - m11 * m34 * m43 - - m31 * m13 * m44 + - m31 * m14 * m43 + - m41 * m13 * m34 - - m41 * m14 * m33; + m11 * m34 * m43 - + m31 * m13 * m44 + + m31 * m14 * m43 + + m41 * m13 * m34 - + m41 * m14 * m33; inv[6] = -m11 * m23 * m44 + - m11 * m24 * m43 + - m21 * m13 * m44 - - m21 * m14 * m43 - - m41 * m13 * m24 + - m41 * m14 * m23; + m11 * m24 * m43 + + m21 * m13 * m44 - + m21 * m14 * m43 - + m41 * m13 * m24 + + m41 * m14 * m23; inv[7] = m11 * m23 * m34 - - m11 * m24 * m33 - - m21 * m13 * m34 + - m21 * m14 * m33 + - m31 * m13 * m24 - - m31 * m14 * m23; + m11 * m24 * m33 - + m21 * m13 * m34 + + m21 * m14 * m33 + + m31 * m13 * m24 - + m31 * m14 * m23; inv[8] = m21 * m32 * m44 - - m21 * m34 * m42 - - m31 * m22 * m44 + - m31 * m24 * m42 + - m41 * m22 * m34 - - m41 * m24 * m32; + m21 * m34 * m42 - + m31 * m22 * m44 + + m31 * m24 * m42 + + m41 * m22 * m34 - + m41 * m24 * m32; inv[9] = -m11 * m32 * m44 + - m11 * m34 * m42 + - m31 * m12 * m44 - - m31 * m14 * m42 - - m41 * m12 * m34 + - m41 * m14 * m32; + m11 * m34 * m42 + + m31 * m12 * m44 - + m31 * m14 * m42 - + m41 * m12 * m34 + + m41 * m14 * m32; inv[10] = m11 * m22 * m44 - - m11 * m24 * m42 - - m21 * m12 * m44 + - m21 * m14 * m42 + - m41 * m12 * m24 - - m41 * m14 * m22; + m11 * m24 * m42 - + m21 * m12 * m44 + + m21 * m14 * m42 + + m41 * m12 * m24 - + m41 * m14 * m22; inv[11] = -m11 * m22 * m34 + - m11 * m24 * m32 + - m21 * m12 * m34 - - m21 * m14 * m32 - - m31 * m12 * m24 + - m31 * m14 * m22; + m11 * m24 * m32 + + m21 * m12 * m34 - + m21 * m14 * m32 - + m31 * m12 * m24 + + m31 * m14 * m22; inv[12] = -m21 * m32 * m43 + - m21 * m33 * m42 + - m31 * m22 * m43 - - m31 * m23 * m42 - - m41 * m22 * m33 + - m41 * m23 * m32; + m21 * m33 * m42 + + m31 * m22 * m43 - + m31 * m23 * m42 - + m41 * m22 * m33 + + m41 * m23 * m32; inv[13] = m11 * m32 * m43 - - m11 * m33 * m42 - - m31 * m12 * m43 + - m31 * m13 * m42 + - m41 * m12 * m33 - - m41 * m13 * m32; + m11 * m33 * m42 - + m31 * m12 * m43 + + m31 * m13 * m42 + + m41 * m12 * m33 - + m41 * m13 * m32; inv[14] = -m11 * m22 * m43 + - m11 * m23 * m42 + - m21 * m12 * m43 - - m21 * m13 * m42 - - m41 * m12 * m23 + - m41 * m13 * m22; + m11 * m23 * m42 + + m21 * m12 * m43 - + m21 * m13 * m42 - + m41 * m12 * m23 + + m41 * m13 * m22; inv[15] = m11 * m22 * m33 - - m11 * m23 * m32 - - m21 * m12 * m33 + - m21 * m13 * m32 + - m31 * m12 * m23 - - m31 * m13 * m22; + m11 * m23 * m32 - + m21 * m12 * m33 + + m21 * m13 * m32 + + m31 * m12 * m23 - + m31 * m13 * m22; T invDet = F(1.0) / det; for (unsigned int i = 0; i < 16; ++i) @@ -326,15 +453,27 @@ namespace Nz return false; } + /*! + * \brief Gets the inverse of this matrix + * \return true if matrix can be inverted + * + * \param dest Matrix to put the result + * + * \remark You can call this method on the same object + * \remark if NAZARA_DEBUG is defined and matrix is not affine, a NazaraWarning is produced and GetInverse is called + * \remark if NAZARA_DEBUG is defined, a NazaraError is produced if dest is null and false is returned + * + * \see GetInverse + */ + template bool Matrix4::GetInverseAffine(Matrix4* dest) const { - ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant - #if NAZARA_MATH_SAFE + #ifdef NAZARA_DEBUG if (!IsAffine()) { - NazaraError("Matrix is not affine"); - return false; + NazaraWarning("Matrix is not affine"); + return GetInverse(dest); } if (!dest) @@ -350,58 +489,58 @@ namespace Nz // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix T inv[16]; inv[0] = m22 * m33 - - m32 * m23; + m32 * m23; inv[1] = -m12 * m33 + - m32 * m13; + m32 * m13; inv[2] = m12 * m23 - - m22 * m13; + m22 * m13; inv[3] = F(0.0); inv[4] = -m21 * m33 + - m31 * m23; + m31 * m23; inv[5] = m11 * m33 - - m31 * m13; + m31 * m13; inv[6] = -m11 * m23 + - m21 * m13; + m21 * m13; inv[7] = F(0.0); inv[8] = m21 * m32 - - m31 * m22; + m31 * m22; inv[9] = -m11 * m32 + - m31 * m12; + m31 * m12; inv[10] = m11 * m22 - - m21 * m12; + m21 * m12; inv[11] = F(0.0); inv[12] = -m21 * m32 * m43 + - m21 * m33 * m42 + - m31 * m22 * m43 - - m31 * m23 * m42 - - m41 * m22 * m33 + - m41 * m23 * m32; + m21 * m33 * m42 + + m31 * m22 * m43 - + m31 * m23 * m42 - + m41 * m22 * m33 + + m41 * m23 * m32; inv[13] = m11 * m32 * m43 - - m11 * m33 * m42 - - m31 * m12 * m43 + - m31 * m13 * m42 + - m41 * m12 * m33 - - m41 * m13 * m32; + m11 * m33 * m42 - + m31 * m12 * m43 + + m31 * m13 * m42 + + m41 * m12 * m33 - + m41 * m13 * m32; inv[14] = -m11 * m22 * m43 + - m11 * m23 * m42 + - m21 * m12 * m43 - - m21 * m13 * m42 - - m41 * m12 * m23 + - m41 * m13 * m22; + m11 * m23 * m42 + + m21 * m12 * m43 - + m21 * m13 * m42 - + m41 * m12 * m23 + + m41 * m13 * m22; T invDet = F(1.0) / det; for (unsigned int i = 0; i < 16; ++i) @@ -416,6 +555,11 @@ namespace Nz return false; } + /*! + * \brief Gets the rotation from this matrix + * \return Quaternion which is the representation of the rotation in this matrix + */ + template Quaternion Matrix4::GetRotation() const { @@ -425,7 +569,7 @@ namespace Nz T trace = m11 + m22 + m33; if (trace > F(0.0)) { - T s = F(0.5)/std::sqrt(trace + F(1.0)); + T s = F(0.5) / std::sqrt(trace + F(1.0)); quat.w = F(0.25) / s; quat.x = (m23 - m32) * s; quat.y = (m31 - m13) * s; @@ -465,6 +609,16 @@ namespace Nz return quat; } + /*! + * \brief Gets the ith row of the matrix + * \return Vector4 which is the ith row of the matrix + * + * \param row Index of the row you want + * + * \remark Produce a NazaraError if you try to access index greater than 3 with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 + */ + template Vector4 Matrix4::GetRow(unsigned int row) const { @@ -473,10 +627,10 @@ namespace Nz #if NAZARA_MATH_SAFE if (row > 3) { - StringStream ss; - ss << "Column out of range: (" << row << ") > 3"; + String error("Row out of range: (" + String::Number(row) + ") > 3"); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif @@ -484,6 +638,13 @@ namespace Nz return Vector4(ptr[row], ptr[row+4], ptr[row+8], ptr[row+12]); } + /*! + * \brief Gets the scale from this matrix + * \return Vector3 which is the representation of the scale in this matrix + * + * \see GetSquaredScale + */ + template Vector3 Matrix4::GetScale() const { @@ -491,35 +652,80 @@ namespace Nz return Vector3(std::sqrt(squaredScale.x), std::sqrt(squaredScale.y), std::sqrt(squaredScale.z)); } + /*! + * \brief Gets the squared scale from this matrix + * \return Vector3 which is the representation of the squared scale in this matrix + * + * \see GetScale + */ + template Vector3 Matrix4::GetSquaredScale() const { return Vector3(m11*m11 + m21*m21 + m31*m31, - m12*m12 + m22*m22 + m32*m32, - m13*m13 + m23*m23 + m33*m33); + m12*m12 + m22*m22 + m32*m32, + m13*m13 + m23*m23 + m33*m33); } + /*! + * \brief Gets the translation from this matrix + * \return Vector3 which is the representation of the translation in this matrix + */ + template Vector3 Matrix4::GetTranslation() const { return Vector3(m41, m42, m43); } + /*! + * \brief Gets the transposed of this matrix + * + * \param dest Matrix to put the result + * + * \remark You can call this method on the same object + * \remark if NAZARA_DEBUG is defined, a NazaraError is produced if dest is null and dest is not changed + * + * \see Transpose + */ + template void Matrix4::GetTransposed(Matrix4* dest) const { + #ifdef NAZARA_DEBUG + if (!dest) + { + NazaraError("Destination matrix must be valid"); + return; + } + #endif + dest->Set(m11, m21, m31, m41, - m12, m22, m32, m42, - m13, m23, m33, m43, - m14, m24, m34, m44); + m12, m22, m32, m42, + m13, m23, m33, m43, + m14, m24, m34, m44); } + /*! + * \brief Checks whetever matrix has negative scale + * \return true if determinant is negative + * + * \see GetDeterminant + */ + template bool Matrix4::HasNegativeScale() const { return GetDeterminant() < F(0.0); } + /*! + * \brief Checks whetever matrix has scale + * \return true if determinant has scale + * + * \see HasNegativeScale + */ + template bool Matrix4::HasScale() const { @@ -538,6 +744,15 @@ namespace Nz return false; } + /*! + * \brief Inverts this matrix + * \return A reference to this matrix inverted + * + * \param bool Optional argument to know if matrix has been successfully inverted + * + * \see InverseAffine + */ + template Matrix4& Matrix4::Inverse(bool* succeeded) { @@ -548,6 +763,15 @@ namespace Nz return *this; } + /*! + * \brief Inverts this matrix + * \return A reference to this matrix inverted + * + * \param bool Optional argument to know if matrix has been successfully inverted + * + * \see Inverse + */ + template Matrix4& Matrix4::InverseAffine(bool* succeeded) { @@ -558,35 +782,63 @@ namespace Nz return *this; } + /*! + * \brief Checks whether the matrix is affine + * \return true if matrix is affine + */ + template bool Matrix4::IsAffine() const { return NumberEquals(m14, F(0.0)) && - NumberEquals(m24, F(0.0)) && - NumberEquals(m34, F(0.0)) && - NumberEquals(m44, F(1.0)); + NumberEquals(m24, F(0.0)) && + NumberEquals(m34, F(0.0)) && + NumberEquals(m44, F(1.0)); } + /*! + * \brief Checks whether the matrix is identity + * \return true if matrix is identity + */ + template bool Matrix4::IsIdentity() const { return (NumberEquals(m11, F(1.0)) && NumberEquals(m12, F(0.0)) && NumberEquals(m13, F(0.0)) && NumberEquals(m14, F(0.0)) && - NumberEquals(m21, F(0.0)) && NumberEquals(m22, F(1.0)) && NumberEquals(m23, F(0.0)) && NumberEquals(m24, F(0.0)) && - NumberEquals(m31, F(0.0)) && NumberEquals(m32, F(0.0)) && NumberEquals(m33, F(1.0)) && NumberEquals(m34, F(0.0)) && - NumberEquals(m41, F(0.0)) && NumberEquals(m42, F(0.0)) && NumberEquals(m43, F(0.0)) && NumberEquals(m44, F(1.0))); + NumberEquals(m21, F(0.0)) && NumberEquals(m22, F(1.0)) && NumberEquals(m23, F(0.0)) && NumberEquals(m24, F(0.0)) && + NumberEquals(m31, F(0.0)) && NumberEquals(m32, F(0.0)) && NumberEquals(m33, F(1.0)) && NumberEquals(m34, F(0.0)) && + NumberEquals(m41, F(0.0)) && NumberEquals(m42, F(0.0)) && NumberEquals(m43, F(0.0)) && NumberEquals(m44, F(1.0))); } + /*! + * \brief Makes the matrix identity (with 1 on diagonal and 0 for others) + * \return A reference to this matrix with components (1 on diagonal and 0 for others) + * + * \see Identity + */ + template Matrix4& Matrix4::MakeIdentity() { Set(F(1.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(1.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(1.0)); + F(0.0), F(1.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); return *this; } + /*! + * \brief Makes the matrix a 'look at matrix' + * \return A reference to this matrix transformed in 'look at matrix' + * + * \param eye Position of the camera + * \param target Position of the target of the camera + * \param up Direction of up vector according to the orientation of camera + * + * \see LookAt + */ + template Matrix4& Matrix4::MakeLookAt(const Vector3& eye, const Vector3& target, const Vector3& up) { @@ -595,25 +847,51 @@ namespace Nz Vector3 u = s.CrossProduct(f); Set(s.x, u.x, -f.x, T(0.0), - s.y, u.y, -f.y, T(0.0), - s.z, u.z, -f.z, T(0.0), - -s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0)); + s.y, u.y, -f.y, T(0.0), + s.z, u.z, -f.z, T(0.0), + -s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0)); return *this; } + /*! + * \brief Makes the matrix a 'orthographic matrix' + * \return A reference to this matrix transformed in 'orthographic matrix' + * + * \param left Distance between center and left + * \param right Distance between center and right + * \param top Distance between center and top + * \param bottom Distance between center and bottom + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see Ortho + */ + template Matrix4& Matrix4::MakeOrtho(T left, T right, T top, T bottom, T zNear, T zFar) { // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204942(v=vs.85).aspx Set(F(2.0) / (right - left), F(0.0), F(0.0), F(0.0), - F(0.0), F(2.0) / (top - bottom), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0) / (zNear - zFar), F(0.0), - (left + right) / (left - right), (top + bottom) / (bottom - top), zNear/(zNear - zFar), F(1.0)); + F(0.0), F(2.0) / (top - bottom), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0) / (zNear - zFar), F(0.0), + (left + right) / (left - right), (top + bottom) / (bottom - top), zNear/(zNear - zFar), F(1.0)); return *this; } + /*! + * \brief Makes the matrix a 'perspective matrix' + * \return A reference to this matrix transformed in 'perspective matrix' + * + * \param angle Unit depends on NAZARA_MATH_ANGLE_RADIAN + * \param ratio Rendering ratio (typically 16/9 or 4/3) + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see Perspective + */ + template Matrix4& Matrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) { @@ -627,19 +905,28 @@ namespace Nz T yScale = std::tan(static_cast(M_PI_2) - angle); Set(yScale / ratio, F(0.0), F(0.0), F(0.0), - F(0.0), yScale, F(0.0), F(0.0), - F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0), - F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0)); + F(0.0), yScale, F(0.0), F(0.0), + F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0), + F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0)); return *this; } + /*! + * \brief Makes the matrix the representation of the quaternion + * \return A reference to this matrix which is the rotation of the quaternion + * + * \param rotation Quaternion representing a rotation of space + * + * \see Rotate + */ + template Matrix4& Matrix4::MakeRotation(const Quaternion& rotation) { SetRotation(rotation); - // On complète la matrice + // We complete the matrix m14 = F(0.0); m24 = F(0.0); m34 = F(0.0); @@ -651,36 +938,66 @@ namespace Nz return *this; } + /*! + * \brief Makes the matrix with the scale + * \return A reference to this matrix which is the scale + * + * \param scale Vector3 representing the homothety + * + * \see Scale + */ + template Matrix4& Matrix4::MakeScale(const Vector3& scale) { Set(scale.x, F(0.0), F(0.0), F(0.0), - F(0.0), scale.y, F(0.0), F(0.0), - F(0.0), F(0.0), scale.z, F(0.0), - F(0.0), F(0.0), F(0.0), F(1.0)); + F(0.0), scale.y, F(0.0), F(0.0), + F(0.0), F(0.0), scale.z, F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); return *this; } + /*! + * \brief Makes the matrix with the translation + * \return A reference to this matrix which is the translation + * + * \param translation Vector3 representing the translation + * + * \see Translate + */ + template Matrix4& Matrix4::MakeTranslation(const Vector3& translation) { Set(F(1.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(1.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0), F(0.0), - translation.x, translation.y, translation.z, F(1.0)); + F(0.0), F(1.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0), F(0.0), + translation.x, translation.y, translation.z, F(1.0)); return *this; } + /*! + * \brief Makes the matrix with the translation and the rotation + * \return A reference to this matrix which is transformation obtained by the translation and the rotation + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \remark Rotation is applied first + * + * \see Transform + */ + template Matrix4& Matrix4::MakeTransform(const Vector3& translation, const Quaternion& rotation) { - // La rotation et la translation peuvent être appliquées directement + // The rotation and the translation may be directly applied SetRotation(rotation); SetTranslation(translation); - // On complète la matrice (les transformations sont affines) + // We complete the matrix (the transformations are affine) m14 = F(0.0); m24 = F(0.0); m34 = F(0.0); @@ -689,40 +1006,77 @@ namespace Nz return *this; } + /*! + * \brief Makes the matrix with the translation, the rotation and the scale + * \return A reference to this matrix which is transformation obtained by the translation, the rotation and the scale + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * \param scale Vector3 representing the homothety + * + * \remark Rotation is applied first, then translation + * + * \see Transform + */ + template Matrix4& Matrix4::MakeTransform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) { MakeTransform(translation, rotation); - // Ensuite on fait une mise à l'échelle des valeurs déjà présentes + // Then we apply the homothety to current values return ApplyScale(scale); } + /*! + * \brief Makes the matrix a 'view matrix' + * \return A reference to this matrix transformed in 'view matrix' + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \see ViewMatrix + */ + template Matrix4& Matrix4::MakeViewMatrix(const Vector3& translation, const Quaternion& rotation) { - // Une matrice de vue doit appliquer une transformation opposée à la matrice "monde" - Quaternion invRot = rotation.GetConjugate(); // Inverse de la rotation + // A view matrix must apply an inverse transformation of the 'world' matrix + Quaternion invRot = rotation.GetConjugate(); // Inverse of the rotation return MakeTransform(-(invRot * translation), invRot); } + /*! + * \brief Makes the matrix zero (with 0 everywhere) + * \return A reference to this matrix with components (0 everywhere) + * + * \see Zero + */ + template Matrix4& Matrix4::MakeZero() { Set(F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0)); + F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0)); return *this; } + /*! + * \brief Sets the components of the matrix + * \return A reference to this matrix + * + * \param rIJ Matrix components at index(I, J) + */ + template Matrix4& Matrix4::Set(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44) + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44) { m11 = r11; m12 = r12; @@ -744,15 +1098,29 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from an array of sixteen elements + * \return A reference to this matrix + * + * \param matrix[16] Matrix components + */ + template Matrix4& Matrix4::Set(const T matrix[16]) { - // Ici nous sommes certains de la continuité des éléments en mémoire - std::memcpy(&m11, matrix, 16*sizeof(T)); + // Here we are confident of the continuity of memory elements + std::memcpy(&m11, matrix, 16 * sizeof(T)); return *this; } + /*! + * \brief Sets the components of the matrix from another matrix + * \return A reference to this matrix + * + * \param matrix The other matrix + */ + template Matrix4& Matrix4::Set(const Matrix4& matrix) { @@ -761,18 +1129,34 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from another type of Matrix4 + * \return A reference to this matrix + * + * \param matrix Matrix4 of type U to convert its components + */ + template template Matrix4& Matrix4::Set(const Matrix4& matrix) { Set(F(matrix[ 0]), F(matrix[ 1]), F(matrix[ 2]), F(matrix[ 3]), - F(matrix[ 4]), F(matrix[ 5]), F(matrix[ 6]), F(matrix[ 7]), - F(matrix[ 8]), F(matrix[ 9]), F(matrix[10]), F(matrix[11]), - F(matrix[12]), F(matrix[13]), F(matrix[14]), F(matrix[15])); + F(matrix[ 4]), F(matrix[ 5]), F(matrix[ 6]), F(matrix[ 7]), + F(matrix[ 8]), F(matrix[ 9]), F(matrix[10]), F(matrix[11]), + F(matrix[12]), F(matrix[13]), F(matrix[14]), F(matrix[15])); return *this; } + /*! + * \brief Sets the components of the matrix from a quaternion + * \return A reference to this matrix which is the rotation of the quaternion + * + * \param rotation Quaternion representing a rotation of space + * + * \remark 3rd column and row are unchanged + */ + template Matrix4& Matrix4::SetRotation(const Quaternion& rotation) { @@ -804,6 +1188,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from a scale + * \return A reference to this matrix which is the scale of the Vector3 + * + * \param scale Vector3 representing the homothety + * + * \remark Components are unchanged, except the three first on the diagonal + */ + template Matrix4& Matrix4::SetScale(const Vector3& scale) { @@ -814,6 +1207,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the matrix from a translation + * \return A reference to this matrix which is the translation of the Vector3 + * + * \param translation Vector3 representing the translation + * + * \remark Components are unchanged, except the three first on the third row + */ + template Matrix4& Matrix4::SetTranslation(const Vector3& translation) { @@ -824,40 +1226,76 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Matrix4(m11, m12, m13, m14,\n ...)" + */ + template String Matrix4::ToString() const { StringStream ss; return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n" - << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" - << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" - << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; + << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" + << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" + << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; } + /*! + * \brief Transforms the Vector2 and two components by the matrix + * \return Vector2 transformed by the matrix + * + * \param vector To transform + * \param z Z Component of the imaginary Vector4 + * \param w W Component of the imaginary Vector4 + */ + template Vector2 Matrix4::Transform(const Vector2& vector, T z, T w) const { - return Vector2(m11*vector.x + m21*vector.y + m31*z + m41*w, - m12*vector.x + m22*vector.y + m32*z + m42*w); + return Vector2(m11 * vector.x + m21 * vector.y + m31 * z + m41 * w, + m12 * vector.x + m22 * vector.y + m32 * z + m42 * w); } + /*! + * \brief Transforms the Vector3 and one component by the matrix + * \return Vector3 transformed by the matrix + * + * \param vector To transform + * \param w W Component of the imaginary Vector4 + */ + template Vector3 Matrix4::Transform(const Vector3& vector, T w) const { - return Vector3(m11*vector.x + m21*vector.y + m31*vector.z + m41*w, - m12*vector.x + m22*vector.y + m32*vector.z + m42*w, - m13*vector.x + m23*vector.y + m33*vector.z + m43*w); + return Vector3(m11 * vector.x + m21 * vector.y + m31 * vector.z + m41 * w, + m12 * vector.x + m22 * vector.y + m32 * vector.z + m42 * w, + m13 * vector.x + m23 * vector.y + m33 * vector.z + m43 * w); } + /*! + * \brief Transforms the Vector4 by the matrix + * \return Vector4 transformed by the matrix + * + * \param vector To transform + */ + template Vector4 Matrix4::Transform(const Vector4& vector) const { - return Vector4(m11*vector.x + m21*vector.y + m31*vector.z + m41*vector.w, - m12*vector.x + m22*vector.y + m32*vector.z + m42*vector.w, - m13*vector.x + m23*vector.y + m33*vector.z + m43*vector.w, - m14*vector.x + m24*vector.y + m34*vector.z + m44*vector.w); + return Vector4(m11 * vector.x + m21 * vector.y + m31 * vector.z + m41 * vector.w, + m12 * vector.x + m22 * vector.y + m32 * vector.z + m42 * vector.w, + m13 * vector.x + m23 * vector.y + m33 * vector.z + m43 * vector.w, + m14 * vector.x + m24 * vector.y + m34 * vector.z + m44 * vector.w); } + /*! + * \brief Transposes the matrix + * \return A reference to this matrix transposed + * + * \see GetTransposed + */ + template Matrix4& Matrix4::Transpose() { @@ -871,51 +1309,87 @@ namespace Nz return *this; } + /*! + * \brief Converts matrix to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 15 is undefined behavior + */ + template - Matrix4::operator T*() + Matrix4::operator T* () { return &m11; } + /*! + * \brief Converts matrix to pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 15 is undefined behavior + */ + template - Matrix4::operator const T*() const + Matrix4::operator const T* () const { return &m11; } + /*! + * \brief Gets the component (x, y) of the matrix + * \return A reference to the component (x, y) + * + * \remark Produce a NazaraError if you try to access index greater than 3 for x or y with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 for x or y + */ + template T& Matrix4::operator()(unsigned int x, unsigned int y) { #if NAZARA_MATH_SAFE if (x > 3 || y > 3) { - StringStream ss; - ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; + String error("Index out of range: (" + String::Number(x) + ", " + String::Number(y) +") > (3, 3)"); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif return (&m11)[y*4+x]; } + /*! + * \brief Gets the component (x, y) of the matrix + * \return The value of the component (x, y) + * + * \remark Produce a NazaraError if you try to access index greater than 3 for x or y with NAZARA_MATH_SAFE defined + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and if you try to access index greater than 3 for x or y + */ + template T Matrix4::operator()(unsigned int x, unsigned int y) const { #if NAZARA_MATH_SAFE if (x > 3 || y > 3) { - StringStream ss; - ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; + String error("Index out of range: (" + String::Number(x) + ", " + String::Number(y) +") > (3, 3)"); - NazaraError(ss); - throw std::out_of_range(ss.ToString()); + NazaraError(error); + throw std::out_of_range(error); } #endif return (&m11)[y*4+x]; } + /*! + * \brief Multiplies the components of the matrix with other matrix + * \return A matrix where components are the product of this matrix and the other one according to matrix product + * + * \param matrix The other matrix to multiply components with + */ + template Matrix4 Matrix4::operator*(const Matrix4& matrix) const { @@ -923,24 +1397,52 @@ namespace Nz return result.Concatenate(matrix); } + /*! + * \brief Multiplies the components of the matrix with a vector + * \return A vector transposed by this matrix + * + * \param vector The vector to multiply the matrix with + */ + template Vector2 Matrix4::operator*(const Vector2& vector) const { return Transform(vector); } + /*! + * \brief Multiplies the components of the matrix with a vector + * \return A vector transposed by this matrix + * + * \param vector The vector to multiply the matrix with + */ + template Vector3 Matrix4::operator*(const Vector3& vector) const { return Transform(vector); } + /*! + * \brief Multiplies the components of the matrix with a vector + * \return A vector transposed by this matrix + * + * \param vector The vector to multiply the matrix with + */ + template Vector4 Matrix4::operator*(const Vector4& vector) const { return Transform(vector); } + /*! + * \brief Multiplies the components of the matrix with a scalar + * \return A Matrix4 where components are the product of matrix'components and the scalar + * + * \param scalar The scalar to multiply the matrix'components with + */ + template Matrix4 Matrix4::operator*(T scalar) const { @@ -951,6 +1453,13 @@ namespace Nz return mat; } + /*! + * \brief Multiplies this matrix with another one + * \return A reference to this matrix which is the product with the other one + * + * \param matrix The matrix to multiply with + */ + template Matrix4& Matrix4::operator*=(const Matrix4& matrix) { @@ -959,6 +1468,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of the matrix with a scalar + * \return A reference to this matrix where components are the product with the scalar + * + * \param scalar The scalar to multiply with + */ + template Matrix4& Matrix4::operator*=(T scalar) { @@ -968,6 +1484,13 @@ namespace Nz return *this; } + /*! + * \brief Compares the matrix to other one + * \return true if the matrices are the same + * + * \param matrix Other matrix to compare with + */ + template bool Matrix4::operator==(const Matrix4& mat) const { @@ -978,30 +1501,64 @@ namespace Nz return true; } + /*! + * \brief Compares the matrix to other one + * \return false if the matrices are the same + * + * \param matrix Other matrix to compare with + */ + template bool Matrix4::operator!=(const Matrix4& mat) const { return !operator==(mat); } + /*! + * \brief Shorthand for the concatenation of two matrices + * \return A Matrix4 which is the product of two + * + * \param left Left-hand side matrix + * \param right Right-hand side matrix + * + * \see Concatenate + */ + template Matrix4 Matrix4::Concatenate(const Matrix4& left, const Matrix4& right) { - Matrix4 matrix(left); // Copie de la matrice de gauche - matrix.Concatenate(right); // Concaténation avec la matrice de droite + Matrix4 matrix(left); // Copy of left-hand side matrix + matrix.Concatenate(right); // Concatenation with right-hand side - return matrix; // Et on renvoie la matrice + return matrix; } + /*! + * \brief Shorthand for the concatenation of two affine matrices + * \return A Matrix4 which is the product of two + * + * \param left Left-hand side matrix + * \param right Right-hand side matrix + * + * \see ConcatenateAffine + */ + template Matrix4 Matrix4::ConcatenateAffine(const Matrix4& left, const Matrix4& right) { - Matrix4 matrix(left); // Copie de la matrice de gauche - matrix.ConcatenateAffine(right); // Concaténation (affine) avec la matrice de droite + Matrix4 matrix(left); // Copy of left-hand side matrix + matrix.ConcatenateAffine(right); // Affine concatenation with right-hand side - return matrix; // Et on renvoie la matrice + return matrix; } + /*! + * \brief Shorthand for the identity matrix + * \return A Matrix4 which is the identity matrix + * + * \see MakeIdentity + */ + template Matrix4 Matrix4::Identity() { @@ -1011,6 +1568,17 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'look at' matrix + * \return A Matrix4 which is the 'look at' matrix + * + * \param eye Position of the camera + * \param target Position of the target of the camera + * \param up Direction of up vector according to the orientation of camera + * + * \see MakeLookAt + */ + template Matrix4 Matrix4::LookAt(const Vector3& eye, const Vector3& target, const Vector3& up) { @@ -1020,6 +1588,20 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'orthographic' matrix + * \return A Matrix4 which is the 'orthographic' matrix + * + * \param left Distance between center and left + * \param right Distance between center and right + * \param top Distance between center and top + * \param bottom Distance between center and bottom + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see MakeOrtho + */ + template Matrix4 Matrix4::Ortho(T left, T right, T top, T bottom, T zNear, T zFar) { @@ -1029,6 +1611,18 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'perspective' matrix + * \return A Matrix4 which is the 'perspective' matrix + * + * \param angle Unit depends on NAZARA_MATH_ANGLE_RADIAN + * \param ratio Rendering ratio (typically 16/9 or 4/3) + * \param zNear Distance where 'vision' begins + * \param zFar Distance where 'vision' ends + * + * \see MakePerspective + */ + template Matrix4 Matrix4::Perspective(T angle, T ratio, T zNear, T zFar) { @@ -1038,6 +1632,15 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'rotation' matrix + * \return A Matrix4 which is the rotation of the quaternion + * + * \param rotation Quaternion representing a rotation of space + * + * \see MakeRotation + */ + template Matrix4 Matrix4::Rotate(const Quaternion& rotation) { @@ -1047,6 +1650,15 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'scale' matrix + * \return A Matrix4 which is is the scale + * + * \param scale Vector3 representing the homothety + * + * \see MakeScale + */ + template Matrix4 Matrix4::Scale(const Vector3& scale) { @@ -1056,6 +1668,15 @@ namespace Nz return matrix; } + /*! + * \brief Shorthand for the 'translation' matrix + * \return A Matrix4 which is is the translation + * + * \param translation Vector3 representing the translation + * + * \see MakeTranslation + */ + template Matrix4 Matrix4::Translate(const Vector3& translation) { @@ -1065,6 +1686,18 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'transform' matrix + * \return A Matrix4 which is transformation obtained by the translation and the rotation + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \remark Rotation is applied first + * + * \see MakeTransform + */ + template Matrix4 Matrix4::Transform(const Vector3& translation, const Quaternion& rotation) { @@ -1074,6 +1707,19 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'transform' matrix + * \return A Matrix4 which is transformation obtained by the translation, the rotation and the scale + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * \param scale Vector3 representing the homothety + * + * \remark Rotation is applied first, then translation + * + * \see MakeTransform + */ + template Matrix4 Matrix4::Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) { @@ -1083,6 +1729,16 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'view' matrix + * \return A Matrix4 which is the 'view matrix' + * + * \param translation Vector3 representing the translation + * \param rotation Quaternion representing a rotation of space + * + * \see MakeViewMatrix + */ + template Matrix4 Matrix4::ViewMatrix(const Vector3& translation, const Quaternion& rotation) { @@ -1092,6 +1748,13 @@ namespace Nz return mat; } + /*! + * \brief Shorthand for the 'zero' matrix + * \return A Matrix4 with components (0 everywhere) + * + * \see MakeZero + */ + template Matrix4 Matrix4::Zero() { @@ -1102,12 +1765,28 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param matrix The matrix to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix) { return out << matrix.ToString(); } +/*! +* \brief Multiplies the components of the matrix with a scalar +* \return A Matrix4 where components are the product of matrix'components and the scalar +* +* \param scale The scalar to multiply the matrix'components with +* \param matrix Matrix to multiply with +*/ + template Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) { From 53f4bacab62b8db1db15b8c34af6f505a2c800f8 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:32:41 +0100 Subject: [PATCH 033/229] Documentation for Plane + add MakeXY methods Former-commit-id: 688a65089e6e332e3a2ffbed7966e4f9185b79cc --- include/Nazara/Math/Plane.hpp | 8 +- include/Nazara/Math/Plane.inl | 266 ++++++++++++++++++++++++++++++++-- 2 files changed, 263 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index cd0856aa5..70bc06051 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -26,8 +26,12 @@ namespace Nz Plane(const Plane& plane) = default; ~Plane() = default; - T Distance(const Vector3& point) const; T Distance(T x, T y, T z) const; + T Distance(const Vector3& point) const; + + Plane& MakeXY(); + Plane& MakeXZ(); + Plane& MakeYZ(); Plane& Set(T normalX, T normalY, T normalZ, T Distance); Plane& Set(const T plane[4]); diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index fceeb9cc3..9b29ab48a 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -11,36 +11,88 @@ namespace Nz { + /*! + * \class Nz::Vector4 + * \brief Math class that represents a plane in 3D + * + * \remark The convention used in this class is: If you ask for plane with normal (0, 1, 0) and distance 1, you will get 0 * X + 1 * Y + 0 * Z - 1 = 0 or Y = 1. Notice the sign minus before the distance on the left side of the equation + */ + + /*! + * \brief Constructs a Plane object from its components + * + * \param normalX X component of the normal + * \param normalY Y component of the normal + * \param normalZ Z component of the normal + * \param D Distance to origin + */ + template Plane::Plane(T normalX, T normalY, T normalZ, T D) { Set(normalX, normalY, normalZ, D); } + /*! + * \brief Constructs a Plane object from an array of four elements + * + * \param plane[4] plane[0] is X component, plane[1] is Y component, plane[2] is Z component and plane[3] is D + */ + template Plane::Plane(const T plane[4]) { Set(plane); } + /*! + * \brief Constructs a Plane object from a normal and a distance + * + * \param Normal normal of the vector + * \param D Distance to origin + */ + template Plane::Plane(const Vector3& Normal, T D) { Set(Normal, D); } + /*! + * \brief Constructs a Plane object from a normal and a point + * + * \param Normal Normal of the plane + * \param point Point which verifies the equation of the plane + */ + template Plane::Plane(const Vector3& Normal, const Vector3& point) { Set(Normal, point); } + /*! + * \brief Constructs a Plane object from three points + * + * \param point1 First point + * \param point2 Second point + * \param point3 Third point + * + * \remark They are expected not to be colinear + */ + template Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3) { Set(point1, point2, point3); } + /*! + * \brief Constructs a Plane object from another type of Plane + * + * \param plane Plane of type U to convert to type T + */ + template template Plane::Plane(const Plane& plane) @@ -48,11 +100,18 @@ namespace Nz Set(plane); } - template - T Plane::Distance(const Vector3& point) const - { - return normal.DotProduct(point) - distance; // ax + by + cd - d = 0. - } + /*! + * \brief Returns the distance from the plane to the point + * \return Distance to the point + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \remark If T is negative, it means that the point is in the opposite direction of the normal + * + * \see Distance + */ template T Plane::Distance(T x, T y, T z) const @@ -60,6 +119,72 @@ namespace Nz return Distance(Vector3(x, y, z)); } + /*! + * \brief Returns the distance from the plane to the point + * \return Distance to the point + * + * \param point Position of the point + * + * \remark If T is negative, it means that the point is in the opposite direction of the normal + * + * \see Distance + */ + + template + T Plane::Distance(const Vector3& point) const + { + return normal.DotProduct(point) - distance; // ax + by + cd - d = 0. + } + + /*! + * \brief Makes the plane (0, 0, 1, 0) + * \return A reference to this plane with components (0, 0, 1, 0) + * + * \see XY + */ + + template + Plane& Plane::MakeXY() + { + return Set(F(0.0), F(0.0), F(1.0), F(0.0)); + } + + /*! + * \brief Makes the plane (0, 1, 0, 0) + * \return A reference to this plane with components (0, 1, 0, 0) + * + * \see XZ + */ + + template + Plane& Plane::MakeXZ() + { + return Set(F(0.0), F(1.0), F(0.0), F(0.0)); + } + + /*! + * \brief Makes the plane (1, 0, 0, 0) + * \return A reference to this plane with components (1, 0, 0, 0) + * + * \see YZ + */ + + template + Plane& Plane::MakeYZ() + { + return Set(F(1.0), F(0.0), F(0.0), F(0.0)); + } + + /*! + * \brief Sets the components of the plane + * \return A reference to this plane + * + * \param normalX X component of the normal + * \param normalY Y component of the normal + * \param normalZ Z component of the normal + * \param D Distance to origin + */ + template Plane& Plane::Set(T normalX, T normalY, T normalZ, T D) { @@ -69,6 +194,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the plane from an array of four elements + * \return A reference to this plane + * + * \param plane[4] plane[0] is X component, plane[1] is Y component, plane[2] is Z component and plane[3] is D + */ + template Plane& Plane::Set(const T plane[4]) { @@ -78,6 +210,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the plane from another plane + * \return A reference to this plane + * + * \param plane The other plane + */ + template Plane& Plane::Set(const Plane& plane) { @@ -86,6 +225,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the plane from a normal and a distance + * \return A reference to this plane + * + * \param Normal Normal of the vector + * \param D Distance to origin + */ + template Plane& Plane::Set(const Vector3& Normal, T D) { @@ -95,6 +242,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the plane from a normal and a point + * \return A reference to this plane + * + * \param Normal Normal of the plane + * \param point Point which verifies the equation of the plane + */ + template Plane& Plane::Set(const Vector3& Normal, const Vector3& point) { @@ -104,6 +259,17 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the plane from three points + * \return A reference to this plane + * + * \param point1 First point + * \param point2 Second point + * \param point3 Third point + * + * \remark They are expected not to be colinear + */ + template Plane& Plane::Set(const Vector3& point1, const Vector3& point2, const Vector3& point3) { @@ -117,6 +283,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the plane from another type of Plane + * \return A reference to this plane + * + * \param plane Plane of type U to convert its components + */ + template template Plane& Plane::Set(const Plane& plane) @@ -127,6 +300,11 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Plane(Normal: Vector3(x, y, z); Distance: w)" + */ + template String Plane::ToString() const { @@ -135,18 +313,50 @@ namespace Nz return ss << "Plane(Normal: " << normal.ToString() << "; Distance: " << distance << ')'; } + /*! + * \brief Compares the plane to other one + * \return true if the planes are the same + * + * \param vec Other vector to compare with + * + * \remark Plane with normal N and distance D is the same than with normal -N et distance -D + */ + template bool Plane::operator==(const Plane& plane) const { return (normal == plane.normal && NumberEquals(distance, plane.distance)) || (normal == -plane.normal && NumberEquals(distance, -plane.distance)); } + /*! + * \brief Compares the plane to other one + * \return false if the planes are the same + * + * \param plane Other plane to compare with + * + * \remark Plane with normal N and distance D is the same than with normal -N et distance -D + */ + template bool Plane::operator!=(const Plane& plane) const { return !operator==(plane); } + /*! + * \brief Interpolates the plane to other one with a factor of interpolation + * \return A new plane which is the interpolation of two planes + * + * \param from Initial plane + * \param to Target plane + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Plane() is returned + * + * \see Lerp + */ + template Plane Plane::Lerp(const Plane& from, const Plane& to, T interpolation) { @@ -159,32 +369,70 @@ namespace Nz #endif Plane plane; - plane.distance = Lerp(from.distance, to.distance, interpolation); + plane.distance = Nz::Lerp(from.distance, to.distance, interpolation); plane.normal = Vector3::Lerp(from.normal, to.normal, interpolation); plane.normal.Normalize(); return plane; } + /*! + * \brief Shorthand for the plane (0, 0, 1, 0) + * \return A plane with components (0, 0, 1, 0) + * + * \see MakeXY + */ + template Plane Plane::XY() { - return Plane(F(0.0), F(0.0), F(1.0), F(0.0)); + Plane plane; + plane.MakeXY(); + + return plane; } + /*! + * \brief Shorthand for the plane (0, 1, 0, 0) + * \return A plane with components (0, 1, 0, 0) + * + * \see MakeXZ + */ + template Plane Plane::XZ() { - return Plane(F(0.0), F(1.0), F(0.0), F(0.0)); + Plane plane; + plane.MakeXZ(); + + return plane; } + /*! + * \brief Shorthand for the plane (1, 0, 0, 0) + * \return A plane with components (1, 0, 0, 0) + * + * \see MakeYZ + */ + template Plane Plane::YZ() { - return Plane(F(1.0), F(0.0), F(0.0), F(0.0)); + Plane plane; + plane.MakeYZ(); + + return plane; } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param plane The plane to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Plane& plane) { From 40d3d6b235b090821f00244e554fd82dec02691b Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:32:59 +0100 Subject: [PATCH 034/229] Documentation for OrientedBox Former-commit-id: 77f7c82d7ca16348774ccdf1d4e98432710a585a --- include/Nazara/Math/OrientedBox.hpp | 4 +- include/Nazara/Math/OrientedBox.inl | 222 ++++++++++++++++++++++++++-- 2 files changed, 215 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 0b579fcba..627f4cbe9 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -43,8 +43,8 @@ namespace Nz void Update(const Matrix4& transformMatrix); void Update(const Vector3& transformMatrix); - operator Vector3*(); - operator const Vector3*() const; + operator Vector3* (); + operator const Vector3* () const; Vector3& operator()(unsigned int i); Vector3 operator()(unsigned int i) const; diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index a54cdae79..c1668118c 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -13,24 +13,62 @@ namespace Nz { + /*! + * \class Nz::OrientedBox + * \brief Math class that represents an oriented three dimensional box + * + * \remark You need to call Update not to have undefined behaviour + */ + + /*! + * \brief Constructs a OrientedBox object from its position and sizes + * + * \param X X component of position + * \param Y Y component of position + * \param Z Z component of position + * \param Width Width of the box (following X) + * \param Height Height of the box (following Y) + * \param Depth Depth of the box (following Z) + */ + template OrientedBox::OrientedBox(T X, T Y, T Z, T Width, T Height, T Depth) { Set(X, Y, Z, Width, Height, Depth); } + /*! + * \brief Constructs a OrientedBox object from a box + * + * \param box Box object + */ + template OrientedBox::OrientedBox(const Box& box) { Set(box); } + /*! + * \brief Constructs a OrientedBox object from two vectors representing point of the space + * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum + * + * \param vec1 First point + * \param vec2 Second point + */ + template OrientedBox::OrientedBox(const Vector3& vec1, const Vector3& vec2) { Set(vec1, vec2); } + /*! + * \brief Constructs a OrientedBox object from another type of OrientedBox + * + * \param orientedBox OrientedBox of type U to convert to type T + */ + template template OrientedBox::OrientedBox(const OrientedBox& orientedBox) @@ -38,6 +76,15 @@ namespace Nz Set(orientedBox); } + /*! + * \brief Gets the Vector3 for the corner + * \return The position of the corner of the oriented box according to enum BoxCorner + * + * \param corner Enumeration of type BoxCorner + * + * \remark If enumeration is not defined in BoxCorner, a NazaraError is thrown and a Vector3 uninitialised is returned + */ + template const Vector3& OrientedBox::GetCorner(BoxCorner corner) const { @@ -54,12 +101,24 @@ namespace Nz return m_corners[corner]; } + /*! + * \brief Checks whether this oriented box is valid + * \return true if the oriented box has a strictly positive width, height and depth + */ + template bool OrientedBox::IsValid() const { return localBox.IsValid(); } + /*! + * \brief Makes the oriented box position (0, 0, 0) and lengths (0, 0, 0) + * \return A reference to this oriented box with position (0, 0, 0) and lengths (0, 0, 0) + * + * \see Zero + */ + template OrientedBox& OrientedBox::MakeZero() { @@ -68,6 +127,18 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the oriented box + * \return A reference to this oriented box + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Width Width of the oriented box (following X) + * \param Height Height of the oriented box (following Y) + * \param Depth Depth of the oriented box (following Z) + */ + template OrientedBox& OrientedBox::Set(T X, T Y, T Z, T Width, T Height, T Depth) { @@ -76,6 +147,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the oriented box from a box + * \return A reference to this oriented box + * + * \param box Box object + */ + template OrientedBox& OrientedBox::Set(const Box& box) { @@ -84,6 +162,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the oriented box with components from another + * \return A reference to this oriented box + * + * \param orientedBox The other OrientedBox + */ + template OrientedBox& OrientedBox::Set(const OrientedBox& orientedBox) { @@ -92,6 +177,14 @@ namespace Nz return *this; } + /*! + * \brief Sets a OrientedBox object from two vectors representing point of the space + * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum + * + * \param vec1 First point + * \param vec2 Second point + */ + template OrientedBox& OrientedBox::Set(const Vector3& vec1, const Vector3& vec2) { @@ -100,6 +193,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the orientedBox from another type of OrientedBox + * \return A reference to this orientedBox + * + * \param orientedBox OrientedBox of type U to convert its components + */ + template template OrientedBox& OrientedBox::Set(const OrientedBox& orientedBox) @@ -112,21 +212,32 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "OrientedBox(...)" + */ + template String OrientedBox::ToString() const { StringStream ss; return ss << "OrientedBox(FLB: " << m_corners[BoxCorner_FarLeftBottom].ToString() << "\n" - << " FLT: " << m_corners[BoxCorner_FarLeftTop].ToString() << "\n" - << " FRB: " << m_corners[BoxCorner_FarRightBottom].ToString() << "\n" - << " FRT: " << m_corners[BoxCorner_FarRightTop].ToString() << "\n" - << " NLB: " << m_corners[BoxCorner_NearLeftBottom].ToString() << "\n" - << " NLT: " << m_corners[BoxCorner_NearLeftTop].ToString() << "\n" - << " NRB: " << m_corners[BoxCorner_NearRightBottom].ToString() << "\n" - << " NRT: " << m_corners[BoxCorner_NearRightTop].ToString() << ")\n"; + << " FLT: " << m_corners[BoxCorner_FarLeftTop].ToString() << "\n" + << " FRB: " << m_corners[BoxCorner_FarRightBottom].ToString() << "\n" + << " FRT: " << m_corners[BoxCorner_FarRightTop].ToString() << "\n" + << " NLB: " << m_corners[BoxCorner_NearLeftBottom].ToString() << "\n" + << " NLT: " << m_corners[BoxCorner_NearLeftTop].ToString() << "\n" + << " NRB: " << m_corners[BoxCorner_NearRightBottom].ToString() << "\n" + << " NRT: " << m_corners[BoxCorner_NearRightTop].ToString() << ")\n"; } + /*! + * \brief Updates the corners of the box + * + * \param transformMatrix Matrix4 which represents the transformation to apply on the local box + */ + template void OrientedBox::Update(const Matrix4& transformMatrix) { @@ -134,6 +245,12 @@ namespace Nz m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast(i))); } + /*! + * \brief Updates the corners of the box + * + * \param translation Vector3 which represents the translation to apply on the local box + */ + template void OrientedBox::Update(const Vector3& translation) { @@ -141,18 +258,40 @@ namespace Nz m_corners[i] = localBox.GetCorner(static_cast(i)) + translation; } + /*! + * \brief Converts oriented box to pointer of Vector3 to its own corners + * \return A pointer to the own corners + * + * \remark Access to index greather than BoxCorner_Max is undefined behavior + */ + template - OrientedBox::operator Vector3*() + OrientedBox::operator Vector3* () { return &m_corners[0]; } + /*! + * \brief Converts oriented box to pointer of Vector3 to its own corners + * \return A const pointer to the own corners + * + * \remark Access to index greather than BoxCorner_Max is undefined behavior + */ + template - OrientedBox::operator const Vector3*() const + OrientedBox::operator const Vector3* () const { return &m_corners[0]; } + /*! + * \brief Gets the ith corner of the oriented box + * \return A reference to this corner + * + * \remark Produce a NazaraError if you try to access to index greather than BoxCorner_Max with NAZARA_MATH_SAFE defined. If not, it is undefined behaviour + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and you try to acces to index greather than BoxCorner_Max + */ + template Vector3& OrientedBox::operator()(unsigned int i) { @@ -170,6 +309,14 @@ namespace Nz return m_corners[i]; } + /*! + * \brief Gets the ith corner of the oriented box + * \return A reference to this corner + * + * \remark Produce a NazaraError if you try to access to index greather than BoxCorner_Max with NAZARA_MATH_SAFE defined. If not, it is undefined behaviour + * \throw std::out_of_range if NAZARA_MATH_SAFE is defined and you try to acces to index greather than BoxCorner_Max + */ + template Vector3 OrientedBox::operator()(unsigned int i) const { @@ -187,6 +334,13 @@ namespace Nz return m_corners[i]; } + /*! + * \brief Multiplies the lengths with the scalar + * \return A OrientedBox where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar + * + * \param scale The scalar to multiply width, height and depth with + */ + template OrientedBox OrientedBox::operator*(T scalar) const { @@ -196,6 +350,13 @@ namespace Nz return box; } + /*! + * \brief Multiplies the lengths of this oriented box with the scalar + * \return A reference to this oriented box where lengths are the product of these lengths and the scalar + * + * \param scalar The scalar to multiply width, height and depth with + */ + template OrientedBox& OrientedBox::operator*=(T scalar) { @@ -204,18 +365,46 @@ namespace Nz return *this; } + /*! + * \brief Compares the oriented box to other one + * \return true if the two oriented boxes are the same + * + * \param box Other oriented box to compare with + */ + template bool OrientedBox::operator==(const OrientedBox& box) const { return localBox == box.localBox; } + /*! + * \brief Compares the oriented box to other one + * \return false if the two oriented boxes are the same + * + * \param box Other oriented box to compare with + */ + template bool OrientedBox::operator!=(const OrientedBox& box) const { return !operator==(box); } + /*! + * \brief Interpolates the oriented box to other one with a factor of interpolation + * \return A new oriented box which is the interpolation of two oriented boxes + * + * \param from Initial oriented box + * \param to Target oriented box + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp + */ + template OrientedBox OrientedBox::Lerp(const OrientedBox& from, const OrientedBox& to, T interpolation) { @@ -225,6 +414,13 @@ namespace Nz return orientedBox; } + /*! + * \brief Shorthand for the oriented box (0, 0, 0, 0, 0, 0) + * \return A oriented box with position (0, 0, 0) and lengths (0, 0, 0) + * + * \see MakeZero + */ + template OrientedBox OrientedBox::Zero() { @@ -235,6 +431,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param orientedBox The orientedBox to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::OrientedBox& orientedBox) { From 9efce81eac02b24597e78b3ec4081d8dda85f3cf Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:33:26 +0100 Subject: [PATCH 035/229] Documentation for Quaternion Former-commit-id: b19bd792823e1f49ff088fc95be26f0db185a8a6 --- include/Nazara/Math/Quaternion.hpp | 10 +- include/Nazara/Math/Quaternion.inl | 463 +++++++++++++++++++++++++---- 2 files changed, 416 insertions(+), 57 deletions(-) diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index b8ca310c1..f33dec0b6 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -19,9 +19,9 @@ namespace Nz public: Quaternion() = default; Quaternion(T W, T X, T Y, T Z); - Quaternion(const T quat[4]); - Quaternion(T angle, const Vector3& axis); Quaternion(const EulerAngles& angles); + Quaternion(T angle, const Vector3& axis); + Quaternion(const T quat[4]); //Quaternion(const Matrix3& mat); template explicit Quaternion(const Quaternion& quat); Quaternion(const Quaternion& quat) = default; @@ -47,9 +47,9 @@ namespace Nz Quaternion& Normalize(T* length = nullptr); Quaternion& Set(T W, T X, T Y, T Z); - Quaternion& Set(const T quat[4]); - Quaternion& Set(T angle, const Vector3& normalizedAxis); Quaternion& Set(const EulerAngles& angles); + Quaternion& Set(T angle, const Vector3& normalizedAxis); + Quaternion& Set(const T quat[4]); //Quaternion& Set(const Matrix3& mat); Quaternion& Set(const Quaternion& quat); template Quaternion& Set(const Quaternion& quat); @@ -60,7 +60,7 @@ namespace Nz //Matrix3 ToRotationMatrix() const; String ToString() const; - Quaternion& operator=(const Quaternion& quat); + Quaternion& operator=(const Quaternion& quat) = default; Quaternion operator+(const Quaternion& quat) const; Quaternion operator*(const Quaternion& quat) const; diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 50c8ec8e3..ea1ce4d3e 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -15,29 +15,67 @@ namespace Nz { + /*! + * \class Nz::Quaternion + * \brief Math class that represents an element of the quaternions + * + * \remark The quaternion is meant to be 'unit' to represent rotations in a three dimensional space + */ + + /*! + * \brief Constructs a Quaternion object from its components + * + * \param W W component + * \param X X component + * \param Y Y component + * \param Z Z component + */ + template Quaternion::Quaternion(T W, T X, T Y, T Z) { Set(W, X, Y, Z); } + /*! + * \brief Constructs a Quaternion object from a EulerAngles + * + * \param angles Easier representation of rotation of space + * + * \see EulerAngles + */ + template - Quaternion::Quaternion(const T quat[4]) + Quaternion::Quaternion(const EulerAngles& angles) { - Set(quat); + Set(angles); } + /*! + * \brief Constructs a Quaternion object from an angle and a direction + * + * \param angle Unit depends of NAZARA_MATH_ANGLE_RADIAN + * \param axis Vector3 which represents a direction, no need to be normalized + */ + template Quaternion::Quaternion(T angle, const Vector3& axis) { Set(angle, axis); } + /*! + * \brief Constructs a Quaternion object from an array of four elements + * + * \param quat[4] quat[0] is W component, quat[1] is X component, quat[2] is Y component and quat[3] is Z component + */ + template - Quaternion::Quaternion(const EulerAngles& angles) + Quaternion::Quaternion(const T quat[4]) { - Set(angles); + Set(quat); } + /* template Quaternion::Quaternion(const Matrix3& mat) @@ -45,6 +83,13 @@ namespace Nz Set(mat); } */ + + /*! + * \brief Constructs a Quaternion object from another type of Quaternion + * + * \param quat Quaternion of type U to convert to type T + */ + template template Quaternion::Quaternion(const Quaternion& quat) @@ -52,6 +97,11 @@ namespace Nz Set(quat); } + /*! + * \brief Computes the w component of the quaternion to make it unit + * \return A reference to this quaternion + */ + template Quaternion& Quaternion::ComputeW() { @@ -65,6 +115,15 @@ namespace Nz return *this; } + /*! + * \brief Returns the rotational conjugate of this quaternion + * \return A reference to this quaternion + * + * The conjugate of a quaternion represents the same rotation in the opposite direction about the rotational axis + * + * \see GetConjugate + */ + template Quaternion& Quaternion::Conjugate() { @@ -75,12 +134,28 @@ namespace Nz return *this; } + /*! + * \brief Calculates the dot (scalar) product with two quaternions + * \return The value of the dot product + * + * \param quat The other quaternion to calculate the dot product with + */ + template T Quaternion::DotProduct(const Quaternion& quat) const { - return w*quat.w + x*quat.x + y*quat.y + z*quat.z; + return w * quat.w + x * quat.x + y * quat.y + z * quat.z; } + /*! + * \brief Gets the rotational conjugate of this quaternion + * \return A new quaternion which is the conjugate of this quaternion + * + * The conjugate of a quaternion represents the same rotation in the opposite direction about the rotational axis + * + * \see Conjugate + */ + template Quaternion Quaternion::GetConjugate() const { @@ -90,6 +165,15 @@ namespace Nz return quat; } + /*! + * \brief Gets the inverse of this quaternion + * \return A new quaternion which is the inverse of this quaternion + * + * \remark If this quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0) + * + * \see Inverse + */ + template Quaternion Quaternion::GetInverse() const { @@ -99,6 +183,17 @@ namespace Nz return quat; } + /*! + * \brief Gets the normalization of this quaternion + * \return A new quaternion which is the normalization of this quaternion + * + * \param length Optional argument to obtain the length's ratio of the quaternion and the unit-length + * + * \remark If this quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0) and length is 0 + * + * \see Normalize + */ + template Quaternion Quaternion::GetNormal(T* length) const { @@ -108,6 +203,15 @@ namespace Nz return quat; } + /*! + * \brief Inverts this quaternion + * \return A reference to this quaternion which is now inverted + * + * \remark If this quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0) + * + * \see GetInverse + */ + template Quaternion& Quaternion::Inverse() { @@ -125,15 +229,34 @@ namespace Nz return *this; } + /*! + * \brief Makes the quaternion (1, 0, 0, 0) + * \return A reference to this vector with components (1, 0, 0, 0) + * + * \see Unit + */ + template Quaternion& Quaternion::MakeIdentity() { return Set(F(1.0), F(0.0), F(0.0), F(0.0)); } + /*! + * \brief Makes this quaternion to the rotation required to rotate direction Vector3 from to direction Vector3 to + * \return A reference to this vector which is the rotation needed + * + * \param from Initial vector + * \param to Target vector + * + * \see RotationBetween + */ + template Quaternion& Quaternion::MakeRotationBetween(const Vector3& from, const Vector3& to) { + // TODO (Gawaboumga): Replace by http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors ? + T dot = from.DotProduct(to); if (NumberEquals(dot, F(-1.0))) { @@ -157,28 +280,55 @@ namespace Nz } } + /*! + * \brief Makes the quaternion (0, 0, 0, 0) + * \return A reference to this vector with components (0, 0, 0, 0) + * + * \see Zero + */ + template Quaternion& Quaternion::MakeZero() { return Set(F(0.0), F(0.0), F(0.0), F(0.0)); } + /*! + * \brief Calculates the magnitude (length) of the quaternion + * \return The magnitude + * + * \see SquaredMagnitude + */ + template T Quaternion::Magnitude() const { return std::sqrt(SquaredMagnitude()); } + /*! + * \brief Normalizes the current quaternion + * \return A reference to this quaternion which is now normalized + * + * \param length Optional argument to obtain the length's ratio of the quaternion and the unit-length + * + * \remark If the quaternion is (0, 0, 0, 0), then it returns (0, 0, 0, 0) and length is 0 + * + * \see GetNormal + */ + template Quaternion& Quaternion::Normalize(T* length) { T norm = std::sqrt(SquaredMagnitude()); - T invNorm = F(1.0) / norm; - - w *= invNorm; - x *= invNorm; - y *= invNorm; - z *= invNorm; + if (norm > F(0.0)) + { + T invNorm = F(1.0) / norm; + w *= invNorm; + x *= invNorm; + y *= invNorm; + z *= invNorm; + } if (length) *length = norm; @@ -186,6 +336,16 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the quaternion + * \return A reference to this quaternion + * + * \param W W component + * \param X X component + * \param Y Y component + * \param Z Z component + */ + template Quaternion& Quaternion::Set(T W, T X, T Y, T Z) { @@ -197,17 +357,29 @@ namespace Nz return *this; } - template - Quaternion& Quaternion::Set(const T quat[4]) - { - w = quat[0]; - x = quat[1]; - y = quat[2]; - z = quat[3]; + /*! + * \brief Sets this quaternion from rotation specified by Euler angle + * \return A reference to this quaternion + * + * \param angles Easier representation of rotation of space + * + * \see EulerAngles + */ - return *this; + template + Quaternion& Quaternion::Set(const EulerAngles& angles) + { + return Set(angles.ToQuaternion()); } + /*! + * \brief Sets this quaternion from rotation specified by axis and angle + * \return A reference to this quaternion + * + * \param angle Unit depends of NAZARA_MATH_ANGLE_RADIAN + * \param axis Vector3 which represents a direction, no need to be normalized + */ + template Quaternion& Quaternion::Set(T angle, const Vector3& axis) { @@ -229,12 +401,46 @@ namespace Nz return Normalize(); } + /*! + * \brief Sets the components of the quaternion from an array of four elements + * \return A reference to this quaternion + * + * \param quat[4] quat[0] is W component, quat[1] is X component, quat[2] is Y component and quat[3] is Z component + */ + template - Quaternion& Quaternion::Set(const EulerAngles& angles) + Quaternion& Quaternion::Set(const T quat[4]) { - return Set(angles.ToQuaternion()); + w = quat[0]; + x = quat[1]; + y = quat[2]; + z = quat[3]; + + return *this; } + /*! + * \brief Sets the components of the quaternion from another quaternion + * \return A reference to this quaternion + * + * \param vec The other quaternion + */ + + template + Quaternion& Quaternion::Set(const Quaternion& quat) + { + std::memcpy(this, &quat, sizeof(Quaternion)); + + return *this; + } + + /*! + * \brief Sets the components of the quaternion from another type of Quaternion + * \return A reference to this quaternion + * + * \param quat Quaternion of type U to convert its components + */ + template template Quaternion& Quaternion::Set(const Quaternion& quat) @@ -247,36 +453,48 @@ namespace Nz return *this; } - template - Quaternion& Quaternion::Set(const Quaternion& quat) - { - std::memcpy(this, &quat, sizeof(Quaternion)); - - return *this; - } + /*! + * \brief Calculates the squared magnitude (length) of the quaternion + * \return The squared magnitude + * + * \see Magnitude + */ template T Quaternion::SquaredMagnitude() const { - return w*w + x*x + y*y + z*z; + return w * w + x * x + y * y + z * z; } + /*! + * \brief Converts this quaternion to Euler angles representation + * \return EulerAngles which is the representation of this rotation + * + * \remark Rotation are "left-handed" + */ + template EulerAngles Quaternion::ToEulerAngles() const { - T test = x*y + z*w; + T test = x * y + z * w; if (test > F(0.499)) // singularity at north pole return EulerAngles(FromDegrees(F(90.0)), FromRadians(F(2.0) * std::atan2(x, w)), F(0.0)); if (test < F(-0.499)) + // singularity at south pole return EulerAngles(FromDegrees(F(-90.0)), FromRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); - return EulerAngles(FromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x*x - F(2.0)*z*z)), - FromRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)), - FromRadians(std::asin(F(2.0)*test))); + return EulerAngles(FromRadians(std::atan2(F(2.0) * x * w - F(2.0) * y * z, F(1.0) - F(2.0) * x * x - F(2.0) * z * z)), + FromRadians(std::atan2(F(2.0) * y * w - F(2.0) * x * z, F(1.0) - F(2.0) * y * y - F(2.0) * z * z)), + FromRadians(std::asin(F(2.0) * test))); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Quaternion(w | x, y, z)" + */ + template String Quaternion::ToString() const { @@ -285,11 +503,12 @@ namespace Nz return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')'; } - template - Quaternion& Quaternion::operator=(const Quaternion& quat) - { - return Set(quat); - } + /*! + * \brief Adds the components of the quaternion with other quaternion + * \return A quaternion where components are the sum of this quaternion and the other one + * + * \param quat The other quaternion to add components with + */ template Quaternion Quaternion::operator+(const Quaternion& quat) const @@ -303,18 +522,32 @@ namespace Nz return result; } + /*! + * \brief Multiplies of the quaternion with other quaternion + * \return A quaternion which is the product of those two according to operator* in quaternions + * + * \param quat The other quaternion to multiply with + */ + template Quaternion Quaternion::operator*(const Quaternion& quat) const { Quaternion result; - result.w = w*quat.w - x*quat.x - y*quat.y - z*quat.z; - result.x = w*quat.x + x*quat.w + y*quat.z - z*quat.y; - result.y = w*quat.y + y*quat.w + z*quat.x - x*quat.z; - result.z = w*quat.z + z*quat.w + x*quat.y - y*quat.x; + result.w = w * quat.w - x * quat.x - y * quat.y - z * quat.z; + result.x = w * quat.x + x * quat.w + y * quat.z - z * quat.y; + result.y = w * quat.y + y * quat.w + z * quat.x - x * quat.z; + result.z = w * quat.z + z * quat.w + x * quat.y - y * quat.x; return result; } + /*! + * \brief Apply the quaternion to the Vector3 + * \return A Vector3f which is the vector rotated by this quaternion + * + * \param vec The vector to multiply with + */ + template Vector3 Quaternion::operator*(const Vector3& vec) const { @@ -327,60 +560,123 @@ namespace Nz return vec + uv + uuv; } + /*! + * \brief Multiplies the components of the quaternion with a scalar + * \return A quaternion where components are the product of this quaternion and the scalar + * + * \param scale The scalar to multiply components with + */ + template Quaternion Quaternion::operator*(T scale) const { return Quaternion(w * scale, - x * scale, - y * scale, - z * scale); + x * scale, + y * scale, + z * scale); } + /*! + * \brief Divides the quaternion with other quaternion + * \return A quaternion which is the quotient of those two according to operator* in quaternions + * + * \param quat The other quaternion to divide with + */ + template Quaternion Quaternion::operator/(const Quaternion& quat) const { return quat.GetConjugate() * (*this); } + /*! + * \brief Adds the components of the quaternion with other quaternion + * \return A reference to this quaternion where components are the sum of this quaternion and the other one + * + * \param quat The other quaternion to add components with + */ + template Quaternion& Quaternion::operator+=(const Quaternion& quat) { return operator=(operator+(quat)); } + /*! + * \brief Multiplies of the quaternion with other quaternion + * \return A reference to this quaternion which is the product of those two according to operator* in quaternions + * + * \param quat The other quaternion to multiply with + */ + template Quaternion& Quaternion::operator*=(const Quaternion& quat) { return operator=(operator*(quat)); } + /*! + * \brief Multiplies the components of the quaternion with a scalar + * \return A reference to this quaternion where components are the product of this quaternion and the scalar + * + * \param scale The scalar to multiply components with + */ + template Quaternion& Quaternion::operator*=(T scale) { return operator=(operator*(scale)); } + /*! + * \brief Divides the quaternion with other quaternion + * \return A reference to this quaternion which is the quotient of those two according to operator* in quaternions + * + * \param quat The other quaternion to divide with + */ + template Quaternion& Quaternion::operator/=(const Quaternion& quat) { return operator=(operator/(quat)); } + /*! + * \brief Compares the quaternion to other one + * \return true if the quaternions are the same + * + * \param vec Other quaternion to compare with + */ + template bool Quaternion::operator==(const Quaternion& quat) const { return NumberEquals(w, quat.w) && - NumberEquals(x, quat.x) && - NumberEquals(y, quat.y) && - NumberEquals(z, quat.z); + NumberEquals(x, quat.x) && + NumberEquals(y, quat.y) && + NumberEquals(z, quat.z); } + /*! + * \brief Compares the quaternion to other one + * \return false if the quaternions are the same + * + * \param vec Other quaternion to compare with + */ + template bool Quaternion::operator!=(const Quaternion& quat) const { return !operator==(quat); } + /*! + * \brief Shorthand for the quaternion (1, 0, 0, 0) + * \return A quaternion with components (1, 0, 0, 0) + * + * \see MakeIdentity + */ + template Quaternion Quaternion::Identity() { @@ -390,6 +686,20 @@ namespace Nz return quaternion; } + /*! + * \brief Interpolates the quaternion to other one with a factor of interpolation + * \return A new quaternion which is the interpolation of two quaternions + * + * \param from Initial quaternion + * \param to Target quaternion + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp, Slerp + */ + template Quaternion Quaternion::Lerp(const Quaternion& from, const Quaternion& to, T interpolation) { @@ -410,12 +720,32 @@ namespace Nz return interpolated; } + /*! + * \brief Gives the normalized quaternion + * \return A normalized quaternion from the quat + * + * \param quat Quaternion to normalize + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \see GetNormal + */ + template Quaternion Quaternion::Normalize(const Quaternion& quat, T* length) { return quat.GetNormal(length); } + /*! + * \brief Gets the rotation required to rotate direction Vector3 from to direction Vector3 to + * \return A quaternion which is the rotation needed between those two Vector3 + * + * \param from Initial vector + * \param to Target vector + * + * \see MakeRotationBetween + */ + template Quaternion Quaternion::RotationBetween(const Vector3& from, const Vector3& to) { @@ -425,6 +755,20 @@ namespace Nz return quaternion; } + /*! + * \brief Interpolates spherically the quaternion to other one with a factor of interpolation + * \return A new quaternion which is the interpolation of two quaternions + * + * \param from Initial quaternion + * \param to Target quaternion + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp + */ + template Quaternion Quaternion::Slerp(const Quaternion& from, const Quaternion& to, T interpolation) { @@ -441,7 +785,7 @@ namespace Nz T cosOmega = from.DotProduct(to); if (cosOmega < F(0.0)) { - // On inverse tout + // We invert everything q.Set(-to.w, -to.x, -to.y, -to.z); cosOmega = -cosOmega; } @@ -451,7 +795,7 @@ namespace Nz T k0, k1; if (cosOmega > F(0.9999)) { - // Interpolation linéaire pour éviter une division par zéro + // Linear interpolation to avoid division by zero k0 = F(1.0) - interpolation; k1 = interpolation; } @@ -460,7 +804,7 @@ namespace Nz T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega); T omega = std::atan2(sinOmega, cosOmega); - // Pour éviter deux divisions + // To avoid two divisions sinOmega = F(1.0)/sinOmega; k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega; @@ -468,9 +812,16 @@ namespace Nz } Quaternion result(k0 * from.w, k0 * from.x, k0 * from.y, k0 * from.z); - return result += q*k1; + return result += q * k1; } + /*! + * \brief Shorthand for the quaternion (0, 0, 0, 0) + * \return A quaternion with components (0, 0, 0, 0) + * + * \see MakeZero + */ + template Quaternion Quaternion::Zero() { @@ -481,6 +832,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param quat The quaternion to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Quaternion& quat) { From 137bc337706f3b045ea33b16cc6da473d71d862b Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:33:55 +0100 Subject: [PATCH 036/229] Documentation for Ray + New method intersection Ray-Triangle Former-commit-id: 29989ec859e609582fdb60a67a7fb353a03091a0 --- include/Nazara/Math/Ray.hpp | 5 +- include/Nazara/Math/Ray.inl | 380 +++++++++++++++++++++++++++++++++--- 2 files changed, 361 insertions(+), 24 deletions(-) diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index e0ae68363..c4c53664d 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -24,9 +24,9 @@ namespace Nz public: Ray() = default; Ray(T X, T Y, T Z, T directionX, T directionY, T directionZ); + Ray(const Vector3& origin, const Vector3& direction); Ray(const T origin[3], const T direction[3]); Ray(const Plane& planeOne, const Plane& planeTwo); - Ray(const Vector3& origin, const Vector3& direction); template explicit Ray(const Ray& ray); template explicit Ray(const Vector3& origin, const Vector3& direction); Ray(const Ray& ray) = default; @@ -42,16 +42,17 @@ namespace Nz bool Intersect(const OrientedBox& orientedBox, T* closestHit = nullptr, T* furthestHit = nullptr) const; bool Intersect(const Plane& plane, T* hit = nullptr) const; bool Intersect(const Sphere& sphere, T* closestHit = nullptr, T* furthestHit = nullptr) const; + bool Intersect(const Vector3& firstPoint, const Vector3& secondPoint, const Vector3& thirdPoint, T* hit = nullptr) const; Ray& MakeAxisX(); Ray& MakeAxisY(); Ray& MakeAxisZ(); Ray& Set(T X, T Y, T Z, T directionX, T directionY, T directionZ); + Ray& Set(const Vector3& origin, const Vector3& direction); Ray& Set(const T origin[3], const T direction[3]); Ray& Set(const Plane& planeOne, const Plane& planeTwo); Ray& Set(const Ray& ray); - Ray& Set(const Vector3& origin, const Vector3& direction); template Ray& Set(const Ray& ray); template Ray& Set(const Vector3& origin, const Vector3& direction); diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 9f65b5382..de2b2d726 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -10,29 +10,77 @@ namespace Nz { + /*! + * \class Nz::Ray + * \brief Math class that represents a ray or a straight line in 3D space + * + * This ray is meant to be understood like origin + lambda * direction, where lambda is a real positive parameter + */ + + /*! + * \brief Constructs a Ray object from its position and direction + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param DirectionX X component of the vector direction + * \param DirectionY Y component of the vector direction + * \param DirectionY Y component of the vector direction + */ + template Ray::Ray(T X, T Y, T Z, T DirectionX, T DirectionY, T DirectionZ) { Set(X, Y, Z, DirectionX, DirectionY, DirectionZ); } + /*! + * \brief Constructs a Ray object from two Vector3 + * + * \param Origin Vector which represents the origin of the ray + * \param Direction Vector which represents the direction of the ray + */ + + template + Ray::Ray(const Vector3& Origin, const Vector3& Direction) + { + Set(Origin, Direction); + } + + /*! + * \brief Constructs a Ray object from two arrays of three elements + * + * \param Origin[3] Origin[0] is X position, Origin[1] is Y position and Origin[2] is Z position + * \param Direction[3] Direction[0] is X direction, Direction[1] is Y direction and Direction[2] is Z direction + */ + template Ray::Ray(const T Origin[3], const T Direction[3]) { Set(Origin, Direction); } + /*! + * \brief Constructs a Ray object from the intersection of two planes + * + * \param planeOne First plane + * \param planeTwo Second secant plane + * + * \remark Produce a NazaraError if planes are parallel with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and planes are parallel + */ + template Ray::Ray(const Plane& planeOne, const Plane& planeTwo) { Set(planeOne, planeTwo); } - template - Ray::Ray(const Vector3& Origin, const Vector3& Direction) - { - Set(Origin, Direction); - } + /*! + * \brief Constructs a Ray object from another type of Ray + * + * \param ray Ray of type U to convert to type T + */ template template @@ -41,6 +89,13 @@ namespace Nz Set(ray); } + /*! + * \brief Constructs a Ray object from two Vector3 from another type of Ray + * + * \param Origin Origin of type U to convert to type T + * \param Direction Direction of type U to convert to type T + */ + template template Ray::Ray(const Vector3& Origin, const Vector3& Direction) @@ -48,6 +103,13 @@ namespace Nz Set(Origin, Direction); } + /*! + * \brief Finds the closest point of the ray from point + * \return The parameter where the point along this ray that is closest to the point provided + * + * \param point The point to get the closest approach to + */ + template T Ray::ClosestPoint(const Vector3& point) const { @@ -55,15 +117,37 @@ namespace Nz T vsq = direction.GetSquaredLength(); T proj = delta.DotProduct(direction); - return proj/vsq; + return proj / vsq; } + /*! + * \brief Gets the point along the ray for this parameter + * \return The point on the ray + * + * \param lambda Parameter to obtain a particular point on the ray + */ + template Vector3 Ray::GetPoint(T lambda) const { return origin + lambda * direction; } + /*! + * \brief Checks whether or not this ray intersects with the BoundingVolume + * \return true if it intersects + * + * \param volume BoundingVolume to check + * \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened + * \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened + * + * \remark If BoundingVolume is Extend_Infinite, then closestHit and furthestHit are equal to 0 et infinity + * \remark If BoundingVolume is Extend_Null, then closestHit and furthestHit are unchanged + * \remark If enumeration of BoundingVolume is not defined in Extend, a NazaraError is thrown and closestHit and furthestHit are unchanged + * + * \see Intersect + */ + template bool Ray::Intersect(const BoundingVolume& volume, T* closestHit, T* furthestHit) const { @@ -96,6 +180,17 @@ namespace Nz return false; } + /*! + * \brief Checks whether or not this ray intersects with the Box + * \return true if it intersects + * + * \param box Box to check + * \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened + * \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened + * + * \see Intersect + */ + template bool Ray::Intersect(const Box& box, T* closestHit, T* furthestHit) const { @@ -142,6 +237,18 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not this ray intersects with the transform Matrix4 applied to the Box + * \return true if it intersects + * + * \param box Box to check + * \param transform Matrix4 which represents the transformation of the box + * \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened + * \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened + * + * \see Intersect + */ + template bool Ray::Intersect(const Box& box, const Matrix4& transform, T* closestHit, T* furthestHit) const { @@ -200,6 +307,17 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not this ray intersects with the OrientedBox + * \return true if it intersects + * + * \param orientedBox OrientedBox to check + * \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened + * \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened + * + * \see Intersect + */ + template bool Ray::Intersect(const OrientedBox& orientedBox, T* closestHit, T* furthestHit) const { @@ -212,9 +330,9 @@ namespace Nz // Construction de la matrice de transformation de l'OBB Matrix4 matrix(width.x, height.x, depth.x, corner.x, - width.y, height.y, depth.y, corner.y, - width.z, height.z, depth.z, corner.z, - F(0.0), F(0.0), F(0.0), F(1.0)); + width.y, height.y, depth.y, corner.y, + width.z, height.z, depth.z, corner.z, + F(0.0), F(0.0), F(0.0), F(1.0)); matrix.InverseAffine(); @@ -227,12 +345,22 @@ namespace Nz return tmpRay.Intersect(tmpBox, closestHit, furthestHit); } + /*! + * \brief Checks whether or not this ray intersects with the plane + * \return true if it intersects + * + * \param plane Plane to check + * \param hit Optional argument to get the parameter where the intersection is only if it happened + * + * \see Intersect + */ + template bool Ray::Intersect(const Plane& plane, T* hit) const { T divisor = plane.normal.DotProduct(direction); if (NumberEquals(divisor, F(0.0))) - return false; // perpendicular + return false; // Perpendicular T lambda = -(plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax + by + cz = d if (lambda < F(0.0)) @@ -244,6 +372,17 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not this ray intersects with the sphere + * \return true if it intersects + * + * \param sphere Sphere to check + * \param closestHit Optional argument to get the closest parameter where the intersection is only if it happened + * \param furthestHit Optional argument to get the furthest parameter where the intersection is only if it happened + * + * \see Intersect + */ + template bool Ray::Intersect(const Sphere& sphere, T* closestHit, T* furthestHit) const { @@ -253,8 +392,8 @@ namespace Nz if (length < F(0.0)) return false; // ray is perpendicular to the vector origin - center - T squaredDistance = sphereRay.GetSquaredLength() - length*length; - T squaredRadius = sphere.radius*sphere.radius; + T squaredDistance = sphereRay.GetSquaredLength() - length * length; + T squaredRadius = sphere.radius * sphere.radius; if (squaredDistance > squaredRadius) return false; // if the ray is further than the radius @@ -274,24 +413,102 @@ namespace Nz return true; } + /*! + * \brief Checks whether or not this ray intersects with the triangle + * \return true if it intersects + * + * \param firstPoint First vertex of the triangle + * \param secondPoint Second vertex of the triangle + * \param thirdPoint Third vertex of the triangle + * \param hit Optional argument to get the parameter where the intersection is only if it happened + * + * \see Intersect + */ + + template + bool Ray::Intersect(const Vector3& firstPoint, const Vector3& secondPoint, const Vector3& thirdPoint, T* hit) const + { + // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm + Vector3 firstEdge = secondPoint - firstPoint; + Vector3 secondEdge = thirdPoint - firstPoint; + + Vector3 P = Vector3::CrossProduct(direction, secondEdge); + const T divisor = firstEdge.DotProduct(P); + if (NumberEquals(divisor, F(0.0))) + return false; // Ray lies in plane of triangle + + Vector3 directionToPoint = origin - firstPoint; + T u = directionToPoint.DotProduct(P) / divisor; + if (u < F(0.0) || u > F(1.0)) + return 0; // The intersection lies outside of the triangle + + Vector3 Q = Vector3::CrossProduct(directionToPoint, firstEdge); + T v = directionToPoint.DotProduct(Q) / divisor; + if (v < F(0.0) || u + v > F(1.0)) + return 0; // The intersection lies outside of the triangle + + T t = secondEdge.DotProduct(Q) / divisor; + if (t > F(0.0)) + { + if (hit) + *hit = t; + return true; + } + + return false; + } + + /*! + * \brief Makes the ray with position (0, 0, 0) and direction (1, 0, 0) + * \return A reference to this ray with position (0, 0, 0) and direction (1, 0, 0) + * + * \see AxisX + */ + template Ray& Ray::MakeAxisX() { return Set(Vector3::Zero(), Vector3::UnitX()); } + /*! + * \brief Makes the ray with position (0, 0, 0) and direction (0, 1, 0) + * \return A reference to this ray with position (0, 0, 0) and direction (0, 1, 0) + * + * \see AxisY + */ + template Ray& Ray::MakeAxisY() { return Set(Vector3::Zero(), Vector3::UnitY()); } + /*! + * \brief Makes the ray with position (0, 0, 0) and direction (0, 0, 1) + * \return A reference to this ray with position (0, 0, 0) and direction (0, 0, 1) + * + * \see AxisZ + */ + template Ray& Ray::MakeAxisZ() { return Set(Vector3::Zero(), Vector3::UnitZ()); } + /*! + * \brief Sets the components of the ray with position and direction + * \return A reference to this ray + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param DirectionX X component of the vector direction + * \param DirectionY Y component of the vector direction + * \param DirectionY Y component of the vector direction + */ + template Ray& Ray::Set(T X, T Y, T Z, T directionX, T directionY, T directionZ) { @@ -301,6 +518,31 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the ray with position and direction + * \return A reference to this ray + * + * \param Origin Vector which represents the origin of the ray + * \param Direction Vector which represents the direction of the ray + */ + + template + Ray& Ray::Set(const Vector3& Origin, const Vector3& Direction) + { + direction = Direction; + origin = Origin; + + return *this; + } + + /*! + * \brief Sets the components of this ray from two arrays of three elements + * \return A reference to this ray + * + * \param Origin[3] Origin[0] is X position, Origin[1] is Y position and Origin[2] is Z position + * \param Direction[3] Direction[0] is X direction, Direction[1] is Y direction and Direction[2] is Z direction + */ + template Ray& Ray::Set(const T Origin[3], const T Direction[3]) { @@ -310,6 +552,17 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of this ray from the intersection of two planes + * \return A reference to this ray + * + * \param planeOne First plane + * \param planeTwo Second secant plane + * + * \remark Produce a NazaraError if planes are parallel with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and planes are parallel + */ + template Ray& Ray::Set(const Plane& planeOne, const Plane& planeTwo) { @@ -321,7 +574,7 @@ namespace Nz #if NAZARA_MATH_SAFE if (NumberEquals(det, F(0.0))) { - String error("Planes are parallel."); + String error("Planes are parallel"); NazaraError(error); throw std::domain_error(error); @@ -338,6 +591,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the ray with components from another + * \return A reference to this ray + * + * \param ray The other ray + */ + template Ray& Ray::Set(const Ray& ray) { @@ -346,14 +606,12 @@ namespace Nz return *this; } - template - Ray& Ray::Set(const Vector3& Origin, const Vector3& Direction) - { - direction = Direction; - origin = Origin; - - return *this; - } + /*! + * \brief Sets the components of the ray from another type of Ray + * \return A reference to this ray + * + * \param ray Ray of type U to convert its components + */ template template @@ -365,6 +623,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the ray from another type of Ray + * \return A reference to this ray + * + * \param Origin Origin of type U to convert to type T + * \param Direction Direction of type U to convert to type T + */ + template template Ray& Ray::Set(const Vector3& Origin, const Vector3& Direction) @@ -375,6 +641,11 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Ray(origin: Vector3(origin.x, origin.y, origin.z), direction: Vector3(direction.x, direction.y, direction.z))" + */ + template String Ray::ToString() const { @@ -383,24 +654,54 @@ namespace Nz return ss << "Ray(origin: " << origin.ToString() << ", direction: " << direction.ToString() << ")"; } + /*! + * \brief Multiplies the direction ray with the lambda to get the point along the ray for this parameter + * \return The point on the ray + * + * \param lambda Parameter to obtain a particular point on the ray + * + * \see GetPoint + */ + template Vector3 Ray::operator*(T lambda) const { return GetPoint(lambda); } + /*! + * \brief Compares the ray to other one + * \return true if the ray are the same + * + * \param rec Other ray to compare with + */ + template bool Ray::operator==(const Ray& ray) const { return direction == ray.direction && origin == ray.origin; } + /*! + * \brief Compares the ray to other one + * \return false if the ray are the same + * + * \param rec Other ray to compare with + */ + template bool Ray::operator!=(const Ray& ray) const { return !operator==(ray); } + /*! + * \brief Shorthand for the ray (0, 0, 0), (1, 0, 0) + * \return A ray with position (0, 0, 0) and direction (1, 0, 0) + * + * \see MakeAxisX + */ + template Ray Ray::AxisX() { @@ -410,6 +711,13 @@ namespace Nz return axis; } + /*! + * \brief Shorthand for the ray (0, 0, 0), (0, 1, 0) + * \return A ray with position (0, 0, 0) and direction (0, 1, 0) + * + * \see MakeAxisY + */ + template Ray Ray::AxisY() { @@ -419,6 +727,13 @@ namespace Nz return axis; } + /*! + * \brief Shorthand for the ray (0, 0, 0), (0, 0, 1) + * \return A ray with position (0, 0, 0) and direction (0, 0, 1) + * + * \see MakeAxisZ + */ + template Ray Ray::AxisZ() { @@ -428,13 +743,34 @@ namespace Nz return axis; } + /*! + * \brief Interpolates the ray to other one with a factor of interpolation + * \return A new ray which is the interpolation of two rectangles + * + * \param from Initial ray + * \param to Target ray + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * + * \see Lerp + */ + template Ray Ray::Lerp(const Ray& from, const Ray& to, T interpolation) { - return Ray(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation)); + return Ray(Nz::Vector3::Lerp(from.origin, to.origin, interpolation), Nz::Vector3::Lerp(from.direction, to.direction, interpolation)); } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param ray The ray to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Ray& ray) { From d733a9c5d14483bb15e4be5e6a945ff5d39d9f9c Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:34:36 +0100 Subject: [PATCH 037/229] Documentation for Rect Former-commit-id: 4cb6ff983f7f01611847d29699dab5ca06e17d4a --- include/Nazara/Math/Rect.hpp | 4 +- include/Nazara/Math/Rect.inl | 420 +++++++++++++++++++++++++++++++++-- 2 files changed, 399 insertions(+), 25 deletions(-) diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index ea468966c..ec203848f 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -28,12 +28,12 @@ namespace Nz ~Rect() = default; bool Contains(T X, T Y) const; - bool Contains(const Vector2& point) const; bool Contains(const Rect& rect) const; + bool Contains(const Vector2& point) const; Rect& ExtendTo(T X, T Y); - Rect& ExtendTo(const Vector2& point); Rect& ExtendTo(const Rect& rect); + Rect& ExtendTo(const Vector2& point); Vector2 GetCenter() const; Vector2 GetCorner(RectCorner corner) const; diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 80c47ae29..82c9e9f3f 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -12,36 +12,89 @@ namespace Nz { + /*! + * \class Nz::Rect + * \brief Math class that represents an axis-aligned rectangle in two dimensions + * + * \remark The basis is said to be "left-hand". It means that with your left hand, the thumb is X positive, the index finger Y positive pointing to the bottom + */ + + /*! + * \brief Constructs a Rect object from its width and height + * + * \param Width Width of the rectangle (following X) + * \param Height Height of the rectangle (following Y) + * + * \remark Position will be (0, 0) + */ + template Rect::Rect(T Width, T Height) { Set(Width, Height); } + /*! + * \brief Constructs a Rect object from its position, width and height + * + * \param X X position + * \param Y Y position + * \param Width Width of the rectangle (following X) + * \param Height Height of the rectangle (following Y) + */ + template Rect::Rect(T X, T Y, T Width, T Height) { Set(X, Y, Width, Height); } + /*! + * \brief Constructs a Rect object from an array of four elements + * + * \param vec[4] vec[0] is X position, vec[1] is Y position, vec[2] is width and vec[3] is height + */ + template Rect::Rect(const T vec[4]) { Set(vec); } + /*! + * \brief Constructs a Rect object from a vector representing width and height + * + * \param lengths (Width, Height) of the rectangle + * + * \remark X and Y will be (0, 0) + */ + template Rect::Rect(const Vector2& lengths) { Set(lengths); } + /*! + * \brief Constructs a Rect object from two vectors representing point of the space + * (X, Y) will be the components minimum of the two vectors and the width and height will be the components maximum - minimum + * + * \param vec1 First point + * \param vec2 Second point + */ + template Rect::Rect(const Vector2& vec1, const Vector2& vec2) { Set(vec1, vec2); } + /*! + * \brief Constructs a Rect object from another type of Rect + * + * \param rect Rect of type U to convert to type T + */ + template template Rect::Rect(const Rect& rect) @@ -49,25 +102,63 @@ namespace Nz Set(rect); } + /*! + * \brief Tests whether the rectangle contains the provided point inclusive of the edge of the rectangle + * \return true if inclusive + * + * \param X X position of the point + * \param Y Y position of the point + * + * \see Contains + */ + template bool Rect::Contains(T X, T Y) const { - return X >= x && X <= x+width && - Y >= y && Y <= y+height; + return X >= x && X <= (x + width) && + Y >= y && Y <= (y + height); } + /*! + * \brief Tests whether the rectangle contains the provided rectangle inclusive of the edge of the rectangle + * \return true if inclusive + * + * \param rect Other rectangle to test + * + * \see Contains + */ + + template + bool Rect::Contains(const Rect& rect) const + { + return Contains(rect.x, rect.y) && + Contains(rect.x + rect.width, rect.y + rect.height); + } + + /*! + * \brief Tests whether the rectangle contains the provided point inclusive of the edge of the rectangle + * \return true if inclusive + * + * \param point Position of the point + * + * \see Contains + */ + template bool Rect::Contains(const Vector2& point) const { return Contains(point.x, point.y); } - template - bool Rect::Contains(const Rect& rect) const - { - return Contains(rect.x, rect.y) && - Contains(rect.x + rect.width, rect.y + rect.height); - } + /*! + * \brief Extends the rectangle to contain the point in the boundary + * \return A reference to this rectangle extended + * + * \param X X position of the point + * \param Y Y position of the point + * + * \see ExtendTo + */ template Rect& Rect::ExtendTo(T X, T Y) @@ -84,11 +175,14 @@ namespace Nz return *this; } - template - Rect& Rect::ExtendTo(const Vector2& point) - { - return ExtendTo(point.x, point.y); - } + /*! + * \brief Extends the rectangle to contain the rectangle + * \return A reference to this rectangle extended + * + * \param rect Other rectangle to contain + * + * \see ExtendTo + */ template Rect& Rect::ExtendTo(const Rect& rect) @@ -105,12 +199,41 @@ namespace Nz return *this; } + /*! + * \brief Extends the rectangle to contain the point in the boundary + * \return A reference to this rectangle extended + * + * \param point Position of the point + * + * \see ExtendTo + */ + + template + Rect& Rect::ExtendTo(const Vector2& point) + { + return ExtendTo(point.x, point.y); + } + + /*! + * \brief Gets a Vector2 for the center + * \return The position of the center of the rectangle + */ + template Vector2 Rect::GetCenter() const { return GetPosition() + GetLengths() / F(2.0); } + /*! + * \brief Gets the Vector2 for the corner + * \return The position of the corner of the rectangle according to enum RectCorner + * + * \param corner Enumeration of type RectCorner + * + * \remark If enumeration is not defined in RectCorner, a NazaraError is thrown and a Vector2 uninitialised is returned + */ + template Vector2 Rect::GetCorner(RectCorner corner) const { @@ -133,25 +256,52 @@ namespace Nz return Vector2(); } + /*! + * \brief Gets a Vector2 for the lengths + * \return The lengths of the rectangle (width, height) + */ + template Vector2 Rect::GetLengths() const { return Vector2(width, height); } + /*! + * \brief Gets a Vector2 for the maximum point + * \return The RectCorner_RightBottom of the rectangle + * + * \see GetCorner + */ + template Vector2 Rect::GetMaximum() const { return GetPosition() + GetLengths(); } + /*! + * \brief Gets a Vector2 for the minimum point + * \return The RectCorner_LeftTop of the rectangle + * + * \see GetCorner, GetPosition + */ + template Vector2 Rect::GetMinimum() const { - ///DOC: Alias de GetPosition() return GetPosition(); } + /*! + * \brief Computes the negative vertex of one direction + * \return The position of the vertex on the rectangle in the opposite way of the normal while considering the center. It means that if the normal has one component negative, the component is set to width or height corresponding to the sign + * + * \param normal Vector indicating a direction + * + * \see GetPositiveVertex + */ + template Vector2 Rect::GetNegativeVertex(const Vector2& normal) const { @@ -166,12 +316,28 @@ namespace Nz return neg; } + /*! + * \brief Gets a Vector2 for the position + * \return The RectCorner_LeftTop of the rectangle + * + * \see GetCorner, GetMinimum + */ + template Vector2 Rect::GetPosition() const { return Vector2(x, y); } + /*! + * \brief Computes the positive vertex of one direction + * \return The position of the vertex on the rectangle in the same way of the normal while considering the center. It means that if the normal has one component positive, the component is set to width or height corresponding to the sign + * + * \param normal Vector indicating a direction + * + * \see GetNegativeVertex + */ + template Vector2 Rect::GetPositiveVertex(const Vector2& normal) const { @@ -186,6 +352,14 @@ namespace Nz return pos; } + /*! + * \brief Checks whether or not this rectangle intersects another one + * \return true if the rectangle intersects + * + * \param rect Rectangle to check + * \param intersection Optional argument for the rectangle which represent the intersection + */ + template bool Rect::Intersect(const Rect& rect, Rect* intersection) const { @@ -210,12 +384,24 @@ namespace Nz return true; } + /*! + * \brief Checks whether this rectangle is valid + * \return true if the rectangle has a strictly positive width and height + */ + template bool Rect::IsValid() const { return width > F(0.0) && height > F(0.0); } + /*! + * \brief Makes the rectangle position (0, 0) and lengths (0, 0) + * \return A reference to this box with position (0, 0) and lengths (0, 0) + * + * \see Zero + */ + template Rect& Rect::MakeZero() { @@ -227,6 +413,16 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the rectangle with width and height + * \return A reference to this rectangle + * + * \param Width Width of the rectangle (following X) + * \param Height Height of the rectangle (following Y) + * + * \remark Position will be (0, 0) + */ + template Rect& Rect::Set(T Width, T Height) { @@ -238,6 +434,16 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the rectangle + * \return A reference to this rectangle + * + * \param X X position + * \param Y Y position + * \param Width Width of the rectangle (following X) + * \param Height Height of the rectangle (following Y) + */ + template Rect& Rect::Set(T X, T Y, T Width, T Height) { @@ -249,6 +455,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the rectangle from an array of four elements + * \return A reference to this rectangle + * + * \param rect[4] rect[0] is X position, rect[1] is Y position, rect[2] is width and rect[3] is height + */ + template Rect& Rect::Set(const T rect[4]) { @@ -260,6 +473,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the rectangle with components from another + * \return A reference to this rectangle + * + * \param rect The other Rect + */ + template Rect& Rect::Set(const Rect& rect) { @@ -268,23 +488,48 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the rectange from a vector representing width and height + * \return A reference to this rectangle + * + * \param lengths (Width, Height) of the rectangle + * + * \remark Position will be (0, 0) + */ + template Rect& Rect::Set(const Vector2& lengths) { return Set(lengths.x, lengths.y); } + /*! + * \brief Sets a Rect object from two vectors representing point of the space + * (X, Y) will be the components minimum of the two vectors and the width and height will be the components maximum - minimum + * \return A reference to this rectangle + * + * \param vec1 First point + * \param vec2 Second point + */ + template Rect& Rect::Set(const Vector2& vec1, const Vector2& vec2) { x = std::min(vec1.x, vec2.x); y = std::min(vec1.y, vec2.y); - width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x; - height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y; + width = (vec2.x > vec1.x) ? vec2.x - vec1.x : vec1.x - vec2.x; + height = (vec2.y > vec1.y) ? vec2.y - vec1.y : vec1.y - vec2.y; return *this; } + /*! + * \brief Sets the components of the rectangle from another type of Rect + * \return A reference to this rectangle + * + * \param rect Rectangle of type U to convert its components + */ + template template Rect& Rect::Set(const Rect& rect) @@ -297,6 +542,11 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Rect(x, y, width, height)" + */ + template String Rect::ToString() const { @@ -305,6 +555,13 @@ namespace Nz return ss << "Rect(" << x << ", " << y << ", " << width << ", " << height << ')'; } + /*! + * \brief Translates the rectangle + * \return A reference to this rectangle translated + * + * \param translation Vector2 which is the translation for the position + */ + template Rect& Rect::Translate(const Vector2& translation) { @@ -314,6 +571,15 @@ namespace Nz return *this; } + /*! + * \brief Returns the ith element of the rectangle + * \return A reference to the ith element of the rectangle + * + * \remark Access to index greather than 4 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 4 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 4 + */ + template T& Rect::operator[](unsigned int i) { @@ -331,6 +597,15 @@ namespace Nz return *(&x+i); } + /*! + * \brief Returns the ith element of the rectangle + * \return A value to the ith element of the rectangle + * + * \remark Access to index greather than 4 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 4 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 4 + */ + template T Rect::operator[](unsigned int i) const { @@ -348,30 +623,65 @@ namespace Nz return *(&x+i); } + /*! + * \brief Multiplies the lengths with the scalar + * \return A rectangle where the position is the same and width and height are the product of the old width and height and the scalar + * + * \param scale The scalar to multiply width and height with + */ + template Rect Rect::operator*(T scalar) const { - return Rect(x, y, width*scalar, height*scalar); + return Rect(x, y, width * scalar, height * scalar); } + /*! + * \brief Multiplies the lengths with the vector + * \return A rectangle where the position is the same and width and height are the product of the old width and height with the vec + * + * \param vec The vector where component one multiply width and two height + */ + template Rect Rect::operator*(const Vector2& vec) const { return Rect(x, y, width*vec.x, height*vec.y); } + /*! + * \brief Divides the lengths with the scalar + * \return A rectangle where the position is the same and width and height are the quotient of the old width and height and the scalar + * + * \param scale The scalar to divide width and height with + */ + template Rect Rect::operator/(T scalar) const { return Rect(x, y, width/scalar, height/scalar); } + /*! + * \brief Divides the lengths with the vector + * \return A rectangle where the position is the same and width and height are the quotient of the old width and height with the vec + * + * \param vec The vector where component one divide width and two height + */ + template Rect Rect::operator/(const Vector2& vec) const { return Rect(x, y, width/vec.x, height/vec.y); } + /*! + * \brief Multiplies the lengths of this rectangle with the scalar + * \return A reference to this rectangle where lengths are the product of these lengths and the scalar + * + * \param scalar The scalar to multiply width and height with + */ + template Rect& Rect::operator*=(T scalar) { @@ -381,6 +691,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the lengths of this rectangle with the vector + * \return A reference to this rectangle where width and height are the product of the old width and height with the vec + * + * \param vec The vector where component one multiply width and two height + */ + template Rect& Rect::operator*=(const Vector2& vec) { @@ -390,6 +707,13 @@ namespace Nz return *this; } + /*! + * \brief Divides the lengths of this rectangle with the scalar + * \return A reference to this rectangle where lengths are the quotient of these lengths and the scalar + * + * \param scalar The scalar to divide width and height with + */ + template Rect& Rect::operator/=(T scalar) { @@ -399,6 +723,13 @@ namespace Nz return *this; } + /*! + * \brief Divives the lengths of this rectangle with the vector + * \return A reference to this rectangle where width and height are the quotient of the old width and height with the vec + * + * \param vec The vector where component one divide width and two height + */ + template Rect& Rect::operator/=(const Vector2& vec) { @@ -408,19 +739,47 @@ namespace Nz return *this; } + /*! + * \brief Compares the rectangle to other one + * \return true if the rectangles are the same + * + * \param rec Other rectangle to compare with + */ + template bool Rect::operator==(const Rect& rect) const { return NumberEquals(x, rect.x) && NumberEquals(y, rect.y) && - NumberEquals(width, rect.width) && NumberEquals(height, rect.height); + NumberEquals(width, rect.width) && NumberEquals(height, rect.height); } + /*! + * \brief Compares the rectangle to other one + * \return false if the rectangles are the same + * + * \param rec Other rectangle to compare with + */ + template bool Rect::operator!=(const Rect& rect) const { return !operator==(rect); } + /*! + * \brief Interpolates the rectangle to other one with a factor of interpolation + * \return A new rectangle which is the interpolation of two rectangles + * + * \param from Initial rectangle + * \param to Target rectangle + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp + */ + template Rect Rect::Lerp(const Rect& from, const Rect& to, T interpolation) { @@ -433,14 +792,21 @@ namespace Nz #endif Rect rect; - rect.x = Lerp(from.x, to.x, interpolation); - rect.y = Lerp(from.y, to.y, interpolation); - rect.width = Lerp(from.width, to.width, interpolation); - rect.height = Lerp(from.height, to.height, interpolation); + rect.x = Nz::Lerp(from.x, to.x, interpolation); + rect.y = Nz::Lerp(from.y, to.y, interpolation); + rect.width = Nz::Lerp(from.width, to.width, interpolation); + rect.height = Nz::Lerp(from.height, to.height, interpolation); return rect; } + /*! + * \brief Shorthand for the rectangle (0, 0, 0, 0) + * \return A rectangle with position (0, 0) and lengths (0, 0) + * + * \see MakeZero + */ + template Rect Rect::Zero() { @@ -451,6 +817,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param rect The rectangle to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Rect& rect) { From cec0567fdd52e518a4e41ce1da675f16b340fe56 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:34:59 +0100 Subject: [PATCH 038/229] Documentation for Sphere + new Unit sphere Former-commit-id: 8f7dd89c3669f0a791b76ef7cb89d998ce6b336a --- include/Nazara/Math/Sphere.hpp | 2 + include/Nazara/Math/Sphere.inl | 355 +++++++++++++++++++++++++++++++-- 2 files changed, 342 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index d3d6daf81..65203c4b0 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -46,6 +46,7 @@ namespace Nz bool IsValid() const; + Sphere& MakeUnit(); Sphere& MakeZero(); Sphere& Set(T X, T Y, T Z, T Radius); @@ -71,6 +72,7 @@ namespace Nz bool operator!=(const Sphere& sphere) const; static Sphere Lerp(const Sphere& from, const Sphere& to, T interpolation); + static Sphere Unit(); static Sphere Zero(); T x, y, z, radius; diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index fb7297d7a..062a7b271 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -13,6 +13,20 @@ namespace Nz { + /*! + * \class Nz::Sphere + * \brief Math class that represents a sphere "S2" in a three dimensional euclidean space + */ + + /*! + * \brief Constructs a Sphere object from its center position and radius + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Radius half of the diameter + */ + template Sphere::Sphere(T X, T Y, T Z, T Radius) { @@ -25,18 +39,38 @@ namespace Nz Set(rect); } */ + + /*! + * \brief Constructs a Sphere object from its position and radius + * + * \param center Center of the sphere + * \param Radius Half of the diameter + */ + template Sphere::Sphere(const Vector3& center, T Radius) { Set(center, Radius); } + /*! + * \brief Constructs a Sphere object from an array of four elements + * + * \param sphere[4] sphere[0] is X component, sphere[1] is Y component, sphere[2] is Z component and sphere[3] is radius + */ + template Sphere::Sphere(const T sphere[4]) { Set(sphere); } + /*! + * \brief Constructs a Sphere object from another type of Sphere + * + * \param sphere Sphere of type U to convert to type T + */ + template template Sphere::Sphere(const Sphere& sphere) @@ -44,12 +78,32 @@ namespace Nz Set(sphere); } + /*! + * \brief Tests whether the sphere contains the provided point inclusive of the edge of the sphere + * \return true if inclusive + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see Contains + */ + template bool Sphere::Contains(T X, T Y, T Z) const { - return SquaredDistance(X, Y, Z) <= radius*radius; + return SquaredDistance(X, Y, Z) <= radius * radius; } + /*! + * \brief Tests whether the sphere contains the provided box inclusive of the edge of the sphere + * \return true if all inclusive + * + * \param box Three dimensional box + * + * \see Contains + */ + template bool Sphere::Contains(const Box& box) const { @@ -61,12 +115,31 @@ namespace Nz return false; } + + /*! + * \brief Tests whether the sphere contains the provided point inclusive of the edge of the sphere + * \return true if inclusive + * + * \param point Position of the point + */ + template bool Sphere::Contains(const Vector3& point) const { return Contains(point.x, point.y, point.z); } + /*! + * \brief Returns the distance from the center of the sphere to the point + * \return Distance to the point + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see SquaredDistance + */ + template T Sphere::Distance(T X, T Y, T Z) const { @@ -74,12 +147,32 @@ namespace Nz return distance.GetLength(); } + /*! + * \brief Returns the distance from the center of the sphere to the point + * \return Distance to the point + * + * \param point Position of the point + * + * \see SquaredDistance + */ + template T Sphere::Distance(const Vector3& point) const { return Distance(point.x, point.y, point.z); } + /*! + * \brief Extends the sphere to contain the point in the boundary + * \return A reference to this sphere extended + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see ExtendTo + */ + template Sphere& Sphere::ExtendTo(T X, T Y, T Z) { @@ -90,12 +183,30 @@ namespace Nz return *this; } + /*! + * \brief Extends the sphere to contain the point in the boundary + * \return A reference to this sphere extended + * + * \param point Position of the point + * + * \see ExtendTo + */ + template Sphere& Sphere::ExtendTo(const Vector3& point) { return ExtendTo(point.x, point.y, point.z); } + /*! + * \brief Computes the negative vertex of one direction + * \return The position of the vertex on the sphere in the opposite way of the normal while considering the center + * + * \param normal Vector normalized indicating a direction + * + * \see GetPositiveVertex + */ + template Vector3 Sphere::GetNegativeVertex(const Vector3& normal) const { @@ -105,12 +216,26 @@ namespace Nz return neg; } + /*! + * \brief Gets a Vector3 of the position + * \return The position of the center of the sphere + */ + template Vector3 Sphere::GetPosition() const { return Vector3(x, y, z); } + /*! + * \brief Computes the positive vertex of one direction + * \return The position of the vertex on the sphere in the same way of the normal while considering the center + * + * \param normal Vector normalized indicating a direction + * + * \see GetNegativeVertex + */ + template Vector3 Sphere::GetPositiveVertex(const Vector3& normal) const { @@ -120,6 +245,13 @@ namespace Nz return pos; } + /*! + * \brief Checks whether or not this sphere intersects a box + * \return true if the box intersects + * + * \param box Box to check + */ + template bool Sphere::Intersect(const Box& box) const { @@ -128,51 +260,88 @@ namespace Nz if (x < box.x) { T diff = x - box.x; - squaredDistance += diff*diff; + squaredDistance += diff * diff; } else if (x > box.x + box.width) { T diff = x - (box.x + box.width); - squaredDistance += diff*diff; + squaredDistance += diff * diff; } if (y < box.y) { T diff = y - box.y; - squaredDistance += diff*diff; + squaredDistance += diff * diff; } else if (y > box.y + box.height) { T diff = y - (box.y + box.height); - squaredDistance += diff*diff; + squaredDistance += diff * diff; } if (z < box.z) { T diff = z - box.z; - squaredDistance += diff*diff; + squaredDistance += diff * diff; } else if (z > box.z + box.depth) { T diff = z - (box.z + box.depth); - squaredDistance += diff*diff; + squaredDistance += diff * diff; } return squaredDistance <= radius * radius; } + /*! + * \brief Checks whether or not this sphere intersects another sphere + * \return true if the spheres intersect or if one is in the other + * + * \param sphere Sphere to check + */ + template bool Sphere::Intersect(const Sphere& sphere) const { - return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius*radius <= sphere.radius*sphere.radius; + return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius * radius <= sphere.radius * sphere.radius; } + /*! + * \brief Checks whether this sphere is valid + * \return true if the sphere has a strictly positive radius + */ + template bool Sphere::IsValid() const { return radius > F(0.0); } + /*! + * \brief Makes the sphere position (0, 0, 0) and radius 1 + * \return A reference to this vector with position (0, 0, 0) and radius 1 + * + * \see Unit + */ + + template + Sphere& Sphere::MakeUnit() + { + x = F(0.0); + y = F(0.0); + z = F(0.0); + radius = F(1.0); + + return *this; + } + + /*! + * \brief Makes the sphere position (0, 0, 0) and radius 0 + * \return A reference to this vector with position (0, 0, 0) and radius 0 + * + * \see Zero + */ + template Sphere& Sphere::MakeZero() { @@ -184,6 +353,16 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere with center and radius + * \return A reference to this sphere + * + * \param X X position + * \param Y Y position + * \param Z Z position + * \param Radius half of the diameter + */ + template Sphere& Sphere::Set(T X, T Y, T Z, T Radius) { @@ -195,6 +374,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere with center and radius + * \return A reference to this sphere + * + * \param center Center of the sphere + * \param Radius Half of the diameter + */ + template Sphere& Sphere::Set(const Vector3& center, T Radius) { @@ -217,6 +404,14 @@ namespace Nz return *this; } */ + + /*! + * \brief Sets the components of the sphere with center and radius from another + * \return A reference to this sphere + * + * \param sphere The other sphere + */ + template Sphere& Sphere::Set(const Sphere& sphere) { @@ -225,6 +420,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere from an array of four elements + * \return A reference to this sphere + * + * \param sphere[4] sphere[0] is X position, sphere[1] is Y position, sphere[2] is Z position and sphere[3] is radius + */ + template Sphere& Sphere::Set(const T sphere[4]) { @@ -236,6 +438,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the sphere from another type of Sphere + * \return A reference to this sphere + * + * \param sphere Sphere of type U to convert its components + */ + template template Sphere& Sphere::Set(const Sphere& sphere) @@ -248,19 +457,44 @@ namespace Nz return *this; } + /*! + * \brief Returns the squared distance from the center of the sphere to the point + * \return Squared distance to the point + * + * \param X X position of the point + * \param Y Y position of the point + * \param Z Z position of the point + * + * \see Distance + */ + template T Sphere::SquaredDistance(T X, T Y, T Z) const { - Vector3 distance(X-x, Y-y, Z-z); + Vector3 distance(X - x, Y - y, Z - z); return distance.GetSquaredLength(); } + /*! + * \brief Returns the squared distance from the center of the sphere to the point + * \return Squared distance to the point + * + * \param point Position of the point + * + * \see Distance + */ + template T Sphere::SquaredDistance(const Vector3& point) const { return SquaredDistance(point.x, point.y, point.z); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Sphere(x, y, z; radius)" + */ + template String Sphere::ToString() const { @@ -269,6 +503,15 @@ namespace Nz return ss << "Sphere(" << x << ", " << y << ", " << z << "; " << radius << ')'; } + /*! + * \brief Returns the ith element of the sphere + * \return A reference to the ith element of the sphere + * + * \remark Access to index greather than 4 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 4 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 4 + */ + template T& Sphere::operator[](unsigned int i) { @@ -286,6 +529,15 @@ namespace Nz return *(&x+i); } + /*! + * \brief Returns the ith element of the sphere + * \return A value to the ith element of the sphere + * + * \remark Access to index greather than 4 is undefined behavior + * \remark Produce a NazaraError if you try to acces to index greather than 4 with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of you try to acces to index greather than 4 + */ + template T Sphere::operator[](unsigned int i) const { @@ -303,31 +555,89 @@ namespace Nz return *(&x+i); } + /*! + * \brief Multiplies the radius of the sphere with a scalar + * \return A sphere where the center is the same and radius is the product of this radius and the scalar + * + * \param scale The scalar to multiply radius with + */ + template Sphere Sphere::operator*(T scalar) const { - return Sphere(x, y, z, radius*scalar); + return Sphere(x, y, z, radius * scalar); } + /*! + * \brief Multiplies the radius of other sphere with a scalar + * \return A reference to this sphere where the center is the same and radius is the product of this radius and the scalar + * + * \param scale The scalar to multiply radius with + */ + template Sphere& Sphere::operator*=(T scalar) { radius *= scalar; } + /*! + * \brief Compares the sphere to other one + * \return true if the spheres are the same + * + * \param sphere Other sphere to compare with + */ + template bool Sphere::operator==(const Sphere& sphere) const { return NumberEquals(x, sphere.x) && NumberEquals(y, sphere.y) && NumberEquals(z, sphere.z) && - NumberEquals(radius, sphere.radius); + NumberEquals(radius, sphere.radius); } + /*! + * \brief Compares the sphere to other one + * \return false if the spheres are the same + * + * \param sphere Other sphere to compare with + */ + template bool Sphere::operator!=(const Sphere& sphere) const { return !operator==(sphere); } + /*! + * \brief Shorthand for the sphere (0, 0, 0, 1) + * \return A sphere with center (0, 0, 0) and radius 1 + * + * \see MakeUnit + */ + + template + Sphere Sphere::Unit() + { + Sphere sphere; + sphere.MakeUnit(); + + return sphere; + } + + /*! + * \brief Interpolates the sphere to other one with a factor of interpolation + * \return A new sphere which is the interpolation of two spheres + * + * \param from Initial sphere + * \param to Target sphere + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * \remark With NAZARA_DEBUG, a NazaraError is thrown and Zero() is returned + * + * \see Lerp + */ + template Sphere Sphere::Lerp(const Sphere& from, const Sphere& to, T interpolation) { @@ -340,14 +650,21 @@ namespace Nz #endif Sphere sphere; - sphere.x = Lerp(from.x, to.x, interpolation); - sphere.y = Lerp(from.y, to.y, interpolation); - sphere.z = Lerp(from.z, to.z, interpolation); - sphere.radius = Lerp(from.radius, to.radius, interpolation); + sphere.x = Nz::Lerp(from.x, to.x, interpolation); + sphere.y = Nz::Lerp(from.y, to.y, interpolation); + sphere.z = Nz::Lerp(from.z, to.z, interpolation); + sphere.radius = Nz::Lerp(from.radius, to.radius, interpolation); return sphere; } + /*! + * \brief Shorthand for the sphere (0, 0, 0, 0) + * \return A sphere with center (0, 0, 0) and radius 0 + * + * \see MakeZero + */ + template Sphere Sphere::Zero() { @@ -358,6 +675,14 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param sphere The sphere to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Sphere& sphere) { From 844e31fb38cdca0fedd851912c7d72ca28a2dcec Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:35:37 +0100 Subject: [PATCH 039/229] Documentation for Vector2 + static DotProduct & Normalize Former-commit-id: 6f0aa15cd725f9dfaa7f6f99b10c6d2dde4e94a1 --- include/Nazara/Math/Vector2.hpp | 6 +- include/Nazara/Math/Vector2.inl | 515 +++++++++++++++++++++++++++++++- 2 files changed, 513 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 28ea44468..3712f0d09 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -62,8 +62,8 @@ namespace Nz String ToString() const; - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; const Vector2& operator+() const; Vector2 operator-() const; @@ -89,7 +89,9 @@ namespace Nz bool operator>(const Vector2& vec) const; bool operator>=(const Vector2& vec) const; + static T DotProduct(const Vector2& vec1, const Vector2& vec2); static Vector2 Lerp(const Vector2& from, const Vector2& to, T interpolation); + static Vector2 Normalize(const Vector2& vec); static Vector2 Unit(); static Vector2 UnitX(); static Vector2 UnitY(); diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 514aa3344..1876087f5 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -13,24 +13,54 @@ namespace Nz { + /*! + * \class Nz::Vector2 + * \brief Math class that represents an element of the two dimensional vector space + */ + + /*! + * \brief Constructs a Vector2 object from its coordinates + * + * \param X X component + * \param Y Y component + */ + template Vector2::Vector2(T X, T Y) { Set(X, Y); } + /*! + * \brief Constructs explicitely a Vector2 object from its "scale" + * + * \param scale X component = Y component + */ + template Vector2::Vector2(T scale) { Set(scale); } + /*! + * \brief Constructs a Vector2 object from an array of two elements + * + * \param vec[2] vec[0] is X component and vec[1] is Y component + */ + template Vector2::Vector2(const T vec[2]) { Set(vec); } + /*! + * \brief Constructs a Vector2 object from another type of Vector2 + * + * \param vec Vector of type U to convert to type T + */ + template template Vector2::Vector2(const Vector2& vec) @@ -38,60 +68,140 @@ namespace Nz Set(vec); } + /*! + * \brief Constructs a Vector2 object from a Vector3 + * + * \param vec Vector3 where only the first two components are taken + */ + template Vector2::Vector2(const Vector3& vec) { Set(vec); } + /*! + * \brief Constructs a Vector2 object from a Vector4 + * + * \param vec Vector4 where only the first two components are taken + */ + template Vector2::Vector2(const Vector4& vec) { Set(vec); } + /*! + * \brief Calculates the absolute dot (scalar) product with two vectors + * \return The dot product with absolutes values on each component + * + * \param vec The other vector to calculate the absolute dot product with + * + * \see DotProduct + */ + template T Vector2::AbsDotProduct(const Vector2& vec) const { return std::abs(x * vec.x) + std::abs(y * vec.y); } + /*! + * \brief Calculates the angle between two vectors in orthonormal basis + * \return The angle unit depends of NAZARA_MATH_ANGLE_RADIAN, you may want to normalize it to the range 0..2*pi with NormalizeAngle + * + * \param vec The other vector to measure the angle with + * + * \remark The vectors do not need to be normalised and if the angle is normalised, it represents the rotation from *this to vec in anti-clockwise direction + * + * \see NormalizeAngle + */ + template T Vector2::AngleBetween(const Vector2& vec) const { return FromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see SquaredDistance + */ + template T Vector2::Distance(const Vector2& vec) const { return std::sqrt(SquaredDistance(vec)); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance in float between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + */ + template float Vector2::Distancef(const Vector2& vec) const { return std::sqrt(static_cast(SquaredDistance(vec))); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec The other vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector2::DotProduct(const Vector2& vec) const { return x*vec.x + y*vec.y; } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length of the vector + * + * \see GetSquaredLength + */ + template T Vector2::GetLength() const { - return std::sqrt(GetSquaredLength()); + return static_cast(std::sqrt(GetSquaredLength())); } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length in float of the vector + */ + template float Vector2::GetLengthf() const { return std::sqrt(static_cast(GetSquaredLength())); } + /*! + * \brief Gets a copy normalized of the vector + * \return A new vector which is the vector normalized + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If this vector is (0, 0), then it returns (0, 0) and length is 0 + * + * \see Normalize + */ + template Vector2 Vector2::GetNormal(T* length) const { @@ -101,36 +211,80 @@ namespace Nz return vec; } + /*! + * \brief Calculates the squared length (magnitude) of the vector + * \return The squared length of the vector + * + * \see GetLength + */ + template T Vector2::GetSquaredLength() const { return x*x + y*y; } + /*! + * \brief Makes the vector (1, 1) + * \return A reference to this vector with components (1, 1) + * + * \see Unit + */ + template Vector2& Vector2::MakeUnit() { return Set(F(1.0), F(1.0)); } + /*! + * \brief Makes the vector (1, 0) + * \return A reference to this vector with components (1, 0) + * + * \see UnitX + */ + template Vector2& Vector2::MakeUnitX() { return Set(F(1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 1) + * \return A reference to this vector with components (0, 1) + * + * \see UnitY + */ + template Vector2& Vector2::MakeUnitY() { return Set(F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 0) + * \return A reference to this vector with components (0, 0) + * + * \see Zero + */ + template Vector2& Vector2::MakeZero() { return Set(F(0.0), F(0.0)); } + /*! + * \brief Sets this vector's components to the maximum of its own and other components + * \return A reference to this vector with replaced values with the corresponding max value + * + * \param vec Other vector to compare the components with + * + * \see Minimize + */ + template Vector2& Vector2::Maximize(const Vector2& vec) { @@ -143,6 +297,15 @@ namespace Nz return *this; } + /*! + * \brief Sets this vector's components to the minimum of its own and other components + * \return A reference to this vector with replaced values with the corresponding min value + * + * \param vec Other vector to compare the components with + * + * \see Maximize + */ + template Vector2& Vector2::Minimize(const Vector2& vec) { @@ -155,6 +318,17 @@ namespace Nz return *this; } + /*! + * \brief Normalizes the current vector + * \return A reference to this vector + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If the vector is (0, 0), then it returns (0, 0) and length is 0 + * + * \see GetNormal + */ + template Vector2& Vector2::Normalize(T* length) { @@ -172,6 +346,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector + * \return A reference to this vector + * + * \param X X component + * \param Y Y component + */ + template Vector2& Vector2::Set(T X, T Y) { @@ -181,6 +363,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a "scale" + * \return A reference to this vector + * + * \param scale X component = Y component + */ + template Vector2& Vector2::Set(T scale) { @@ -190,6 +379,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from an array of two elements + * \return A reference to this vector + * + * \param vec[2] vec[0] is X component and vec[1] is Y component + */ + template Vector2& Vector2::Set(const T vec[2]) { @@ -198,6 +394,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another vector + * \return A reference to this vector + * + * \param vec The other vector + */ + template Vector2& Vector2::Set(const Vector2& vec) { @@ -206,6 +409,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another type of Vector2 + * \return A reference to this vector + * + * \param vec Vector of type U to convert its components + */ + template template Vector2& Vector2::Set(const Vector2& vec) @@ -216,6 +426,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector3 + * \return A reference to this vector + * + * \param vec Vector3 where only the first two components are taken + */ + template Vector2& Vector2::Set(const Vector3& vec) { @@ -225,6 +442,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector4 + * \return A reference to this vector + * + * \param vec Vector4 where only the first two components are taken + */ + template Vector2& Vector2::Set(const Vector4& vec) { @@ -234,12 +458,26 @@ namespace Nz return *this; } + /*! + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see Distance + */ + template T Vector2::SquaredDistance(const Vector2& vec) const { return (*this - vec).GetSquaredLength(); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Vector2(x, y)" + */ + template String Vector2::ToString() const { @@ -248,54 +486,116 @@ namespace Nz return ss << "Vector2(" << x << ", " << y << ')'; } + /*! + * \brief Converts vector to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 1 is undefined behavior + */ + template - Vector2::operator T*() + Vector2::operator T* () { return &x; } + /*! + * \brief Converts vector to const pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 1 is undefined behavior + */ + template - Vector2::operator const T*() const + Vector2::operator const T* () const { return &x; } + /*! + * \brief Helps to represent the sign of the vector + * \return A constant reference to this vector + */ + template const Vector2& Vector2::operator+() const { return *this; } + /*! + * \brief Negates the components of the vector + * \return A constant reference to this vector with negate components + */ + template Vector2 Vector2::operator-() const { return Vector2(-x, -y); } + /*! + * \brief Adds the components of the vector with other vector + * \return A vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector2 Vector2::operator+(const Vector2& vec) const { return Vector2(x + vec.x, y + vec.y); } + /*! + * \brief Substracts the components of the vector with other vector + * \return A vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector2 Vector2::operator-(const Vector2& vec) const { return Vector2(x - vec.x, y - vec.y); } + /*! + * \brief Multiplies the components of the vector with other vector + * \return A vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector2 Vector2::operator*(const Vector2& vec) const { return Vector2(x * vec.x, y * vec.y); } + /*! + * \brief Multiplies the components of the vector with a scalar + * \return A vector where components are the product of this vector and the scalar + * + * \param scale The scalar to multiply components with + */ + template Vector2 Vector2::operator*(T scale) const { return Vector2(x * scale, y * scale); } + /*! + * \brief Divides the components of the vector with other vector + * \return A vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector2 Vector2::operator/(const Vector2& vec) const { @@ -312,6 +612,16 @@ namespace Nz return Vector2(x / vec.x, y / vec.y); } + /*! + * \brief Divides the components of the vector with a scalar + * \return A vector where components are the quotient of this vector and the scalar + * + * \param scale The scalar to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector2 Vector2::operator/(T scale) const { @@ -328,6 +638,13 @@ namespace Nz return Vector2(x / scale, y / scale); } + /*! + * \brief Adds the components of other vector to this vector + * \return A reference to this vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector2& Vector2::operator+=(const Vector2& vec) { @@ -337,6 +654,13 @@ namespace Nz return *this; } + /*! + * \brief Substracts the components of other vector to this vector + * \return A reference to this vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector2& Vector2::operator-=(const Vector2& vec) { @@ -346,6 +670,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector2& Vector2::operator*=(const Vector2& vec) { @@ -355,6 +686,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector with a scalar + * \return A reference to this vector where components are the product of this vector and the scalar + * + * \param vec The other vector to multiply components with + */ + template Vector2& Vector2::operator*=(T scale) { @@ -364,6 +702,16 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to multiply components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector2& Vector2::operator/=(const Vector2& vec) { @@ -383,6 +731,16 @@ namespace Nz return *this; } + /*! + * \brief Divides the components of other vector with a scalar + * \return A reference to this vector where components are the quotient of this vector and the scalar + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector2& Vector2::operator/=(T scale) { @@ -402,19 +760,40 @@ namespace Nz return *this; } + /*! + * \brief Compares the vector to other one + * \return true if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator==(const Vector2& vec) const { return NumberEquals(x, vec.x) && - NumberEquals(y, vec.y); + NumberEquals(y, vec.y); } + /*! + * \brief Compares the vector to other one + * \return false if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator!=(const Vector2& vec) const { return !operator==(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator<(const Vector2& vec) const { @@ -424,6 +803,13 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator<=(const Vector2& vec) const { @@ -433,24 +819,95 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator>(const Vector2& vec) const { return !operator<=(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector2::operator>=(const Vector2& vec) const { return !operator<(vec); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec1 The first vector to calculate the dot product with + * \param vec2 The second vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + + template + T Vector2::DotProduct(const Vector2& vec1, const Vector2& vec2) + { + return vec1.DotProduct(vec2); + } + + /*! + * \brief Interpolates the vector to other one with a factor of interpolation + * \return A new vector which is the interpolation of two vectors + * + * \param from Initial vector + * \param to Target vector + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * + * \see Lerp + */ + template Vector2 Vector2::Lerp(const Vector2& from, const Vector2& to, T interpolation) { - return Lerp(from, to, interpolation); + Vector2 dummy; + dummy.x = Nz::Lerp(from.x, to.x, interpolation); + dummy.y = Nz::Lerp(from.y, to.y, interpolation); + + return dummy; } + /*! + * \brief Gives the normalized vector + * \return A normalized vector from the vec + * + * \param vec Vector to normalize + * + * \remark If the vector is (0, 0), then it returns (0, 0) + * + * \see GetNormal + */ + + template + Vector2 Vector2::Normalize(const Vector2& vec) + { + return vec.GetNormal(); + } + + /*! + * \brief Shorthand for the vector (1, 1) + * \return A vector with components (1, 1) + * + * \see MakeUnit + */ + template Vector2 Vector2::Unit() { @@ -460,6 +917,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (1, 0) + * \return A vector with components (1, 0) + * + * \see MakeUnitX + */ + template Vector2 Vector2::UnitX() { @@ -469,6 +933,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1) + * \return A vector with components (0, 1) + * + * \see MakeUnitY + */ + template Vector2 Vector2::UnitY() { @@ -478,6 +949,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0) + * \return A vector with components (0, 0) + * + * \see MakeZero + */ + template Vector2 Vector2::Zero() { @@ -488,18 +966,43 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param vec The vector to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec) { return out << vec.ToString(); } +/*! +* \brief Multiplies the components of the vector with a scalar +* \return A vector where components are the product of this vector and the scalar +* +* \param scale The scalar to multiply components with +*/ + template Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) { return Nz::Vector2(scale * vec.x, scale * vec.y); } +/*! +* \brief Divides the components of the vector with a scalar +* \return A vector where components are the quotient of this vector and the scalar +* +* \param scale The scalar to divide components with +* +* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined +* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null +*/ + template Nz::Vector2 operator/(T scale, const Nz::Vector2& vec) { @@ -513,7 +1016,7 @@ Nz::Vector2 operator/(T scale, const Nz::Vector2& vec) } #endif - return Nz::Vector2(scale/vec.x, scale/vec.y); + return Nz::Vector2(scale / vec.x, scale / vec.y); } #undef F From 95400fdfab19f6a0ca366d0682c24232cde24ccb Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:36:12 +0100 Subject: [PATCH 040/229] Documentation for Vector3 Former-commit-id: 15f770065aa66e03928d7086403c697be334cb3a --- include/Nazara/Math/Vector3.hpp | 4 +- include/Nazara/Math/Vector3.inl | 644 +++++++++++++++++++++++++++++++- 2 files changed, 639 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 5f14f8be7..0ab620406 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -73,8 +73,8 @@ namespace Nz String ToString() const; - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; const Vector3& operator+() const; Vector3 operator-() const; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 9a04ad97b..a1807c902 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -13,36 +13,83 @@ namespace Nz { + /*! + * \class Nz::Vector2 + * \brief Math class that represents an element of the three dimensional vector space + * + * \remark The basis is said to be "right-hand". It means that with your right hand, the thumb is X positive, the index finger Y positive and the middle finger (pointing to you) Z positive + */ + + /*! + * \brief Constructs a Vector3 object from its coordinates + * + * \param X X component + * \param Y Y component + * \param Z Z component + */ + template Vector3::Vector3(T X, T Y, T Z) { Set(X, Y, Z); } + /*! + * \brief Constructs a Vector3 object from a component and a Vector2 + * + * \param X X component + * \param vec vec.X = Y component and vec.y = Z component + */ + template Vector3::Vector3(T X, const Vector2& vec) { Set(X, vec); } + /*! + * \brief Constructs explicitely a Vector3 object from its "scale" + * + * \param scale X component = Y component = Z component + */ + template Vector3::Vector3(T scale) { Set(scale); } + /*! + * \brief Constructs a Vector3 object from an array of three elements + * + * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component + */ + template Vector3::Vector3(const T vec[3]) { Set(vec); } + /*! + * \brief Constructs a Vector3 object from a Vector2 and a component + * + * \param vec vec.X = X component and vec.y = Y component + * \param Z Z component + */ + template Vector3::Vector3(const Vector2& vec, T Z) { Set(vec, Z); } + /*! + * \brief Constructs a Vector3 object from another type of Vector3 + * + * \param vec Vector of type U to convert to type T + */ + template template Vector3::Vector3(const Vector3& vec) @@ -50,18 +97,46 @@ namespace Nz Set(vec); } + /*! + * \brief Constructs a Vector3 object from a Vector4 + * + * \param vec Vector4 where only the first three components are taken + */ + template Vector3::Vector3(const Vector4& vec) { Set(vec); } + /*! + * \brief Calculates the absolute dot (scalar) product with two vectors + * \return The dot product with absolutes values on each component + * + * \param vec The other vector to calculate the absolute dot product with + * + * \see DotProduct + */ + template T Vector3::AbsDotProduct(const Vector3& vec) const { return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z); } + /*! + * \brief Calculates the angle between two vectors in orthonormal basis + * \return The angle unit depends of NAZARA_MATH_ANGLE_RADIAN in the range 0..pi + * + * \param vec The other vector to measure the angle with + * + * \remark The vectors do not need to be normalised + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + * + * \see NormalizeAngle + */ + template T Vector3::AngleBetween(const Vector3& vec) const { @@ -78,46 +153,103 @@ namespace Nz } #endif - T alpha = DotProduct(vec)/divisor; + T alpha = DotProduct(vec) / divisor; return FromRadians(std::acos(Clamp(alpha, F(-1.0), F(1.0)))); } + /*! + * \brief Calculates the cross (scalar) product with two vectors + * \return The vector of the cross product according to "right-hand" rule + * + * \param vec The other vector to calculate the cross product with + * + * \see CrossProduct + */ + template Vector3 Vector3::CrossProduct(const Vector3& vec) const { return Vector3(y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see SquaredDistance + */ + template T Vector3::Distance(const Vector3& vec) const { return std::sqrt(SquaredDistance(vec)); } + /*! + * \brief Calculates the distance between two vectors + * \return The metric distance in float between two vectors with euclidean norm + * + * \param vec The other vector to measure the distance with + */ + template float Vector3::Distancef(const Vector3& vec) const { return std::sqrt(static_cast(SquaredDistance(vec))); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec The other vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector3::DotProduct(const Vector3& vec) const { - return x*vec.x + y*vec.y + z*vec.z; + return x * vec.x + y * vec.y + z * vec.z; } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length of the vector + * + * \see GetSquaredLength + */ + template T Vector3::GetLength() const { return static_cast(std::sqrt(GetSquaredLength())); } + /*! + * \brief Calculates the length (magnitude) of the vector + * \return The length in float of the vector + */ + template float Vector3::GetLengthf() const { return std::sqrt(static_cast(GetSquaredLength())); } + /*! + * \brief Gets a copy normalized of the vector + * \return A new vector which is the vector normalized + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If ths vector is (0, 0, 0), then it returns (0, 0, 0) and length is 0 + * + * \see Normalize + */ + template Vector3 Vector3::GetNormal(T* length) const { @@ -127,78 +259,171 @@ namespace Nz return vec; } + /*! + * \brief Calculates the squared length (magnitude) of the vector + * \return The squared length of the vector + * + * \see GetLength + */ + template T Vector3::GetSquaredLength() const { return x*x + y*y + z*z; } + /*! + * \brief Makes the vector (0, 0, 1) + * \return A reference to this vector with components (0, 0, 1) + * + * \see Backward + */ + template Vector3& Vector3::MakeBackward() { return Set(F(0.0), F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, -1, 0) + * \return A reference to this vector with components (0, -1, 0) + * + * \see Down + */ + template Vector3& Vector3::MakeDown() { return Set(F(0.0), F(-1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 0, -1) + * \return A reference to this vector with components (0, 0, -1) + * + * \see Forward + */ + template Vector3& Vector3::MakeForward() { return Set(F(0.0), F(0.0), F(-1.0)); } + /*! + * \brief Makes the vector (-1, 0, 0) + * \return A reference to this vector with components (-1, 0, 0) + * + * \see Left + */ + template Vector3& Vector3::MakeLeft() { return Set(F(-1.0), F(0.0), F(0.0)); } + /*! + * \brief Makes the vector (1, 0, 0) + * \return A reference to this vector with components (1, 0, 0) + * + * \see Right + */ + template Vector3& Vector3::MakeRight() { return Set(F(1.0), F(0.0), F(0.0)); } + /*! + * \brief Makes the vector (1, 1, 1) + * \return A reference to this vector with components (1, 1, 1) + * + * \see Unit + */ + template Vector3& Vector3::MakeUnit() { return Set(F(1.0), F(1.0), F(1.0)); } + /*! + * \brief Makes the vector (1, 0, 0) + * \return A reference to this vector with components (1, 0, 0) + * + * \see UnitX + */ + template Vector3& Vector3::MakeUnitX() { return Set(F(1.0), F(0.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 1, 0) + * \return A reference to this vector with components (0, 1, 0) + * + * \see UnitY + */ + template Vector3& Vector3::MakeUnitY() { return Set(F(0.0), F(1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 0, 1) + * \return A reference to this vector with components (0, 0, 1) + * + * \see UnitZ + */ + template Vector3& Vector3::MakeUnitZ() { return Set(F(0.0), F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 1, 0) + * \return A reference to this vector with components (0, 1, 0) + * + * \see Up + */ + template Vector3& Vector3::MakeUp() { return Set(F(0.0), F(1.0), F(0.0)); } + /*! + * \brief Makes the vector (0, 0, 0) + * \return A reference to this vector with components (0, 0, 0) + * + * \see Zero + */ + template Vector3& Vector3::MakeZero() { return Set(F(0.0), F(0.0), F(0.0)); } + /*! + * \brief Sets this vector's components to the maximum of its own and other components + * \return A reference to this vector with replaced values with the corresponding max value + * + * \param vec Other vector to compare the components with + * + * \see Minimize + */ + template Vector3& Vector3::Maximize(const Vector3& vec) { @@ -214,6 +439,15 @@ namespace Nz return *this; } + /*! + * \brief Sets this vector's components to the minimum of its own and other components + * \return A reference to this vector with replaced values with the corresponding min value + * + * \param vec Other vector to compare the components with + * + * \see Maximize + */ + template Vector3& Vector3::Minimize(const Vector3& vec) { @@ -229,6 +463,17 @@ namespace Nz return *this; } + /*! + * \brief Normalizes the current vector + * \return A reference to this vector + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length + * + * \remark If the vector is (0, 0, 0), then it returns (0, 0, 0) and length is 0 + * + * \see GetNormal + */ + template Vector3& Vector3::Normalize(T* length) { @@ -247,6 +492,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector + * \return A reference to this vector + * + * \param X X component + * \param Y Y component + * \param Z Z component + */ + template Vector3& Vector3::Set(T X, T Y, T Z) { @@ -257,6 +511,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a component and a Vector2 + * + * \param X X component + * \param vec vec.X = Y component and vec.y = Z component + */ + template Vector3& Vector3::Set(T X, const Vector2& vec) { @@ -267,6 +528,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a "scale" + * \return A reference to this vector + * + * \param scale X component = Y component = Z component + */ + template Vector3& Vector3::Set(T scale) { @@ -277,6 +545,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from an array of three elements + * \return A reference to this vector + * + * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component + */ + template Vector3& Vector3::Set(const T vec[3]) { @@ -285,6 +560,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector2 and a component + * + * \param vec vec.X = X component and vec.y = Y component + * \param Z Z component + */ + template Vector3& Vector3::Set(const Vector2& vec, T Z) { @@ -295,6 +577,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another vector + * \return A reference to this vector + * + * \param vec The other vector + */ + template Vector3& Vector3::Set(const Vector3& vec) { @@ -303,6 +592,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another type of Vector3 + * \return A reference to this vector + * + * \param vec Vector of type U to convert its components + */ + template template Vector3& Vector3::Set(const Vector3& vec) @@ -314,6 +610,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector4 + * \return A reference to this vector + * + * \param vec Vector4 where only the first three components are taken + */ + template Vector3& Vector3::Set(const Vector4& vec) { @@ -324,12 +627,26 @@ namespace Nz return *this; } + /*! + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm + * + * \param vec The other vector to measure the distance with + * + * \see Distance + */ + template T Vector3::SquaredDistance(const Vector3& vec) const { return (*this - vec).GetSquaredLength(); } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Vector3(x, y, z)" + */ + template String Vector3::ToString() const { @@ -338,54 +655,116 @@ namespace Nz return ss << "Vector3(" << x << ", " << y << ", " << z <<')'; } + /*! + * \brief Converts vector to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 2 is undefined behavior + */ + template - Vector3::operator T*() + Vector3::operator T* () { return &x; } + /*! + * \brief Converts vector to const pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 2 is undefined behavior + */ + template - Vector3::operator const T*() const + Vector3::operator const T* () const { return &x; } + /*! + * \brief Helps to represent the sign of the vector + * \return A constant reference to this vector + */ + template const Vector3& Vector3::operator+() const { return *this; } + /*! + * \brief Negates the components of the vector + * \return A constant reference to this vector with negate components + */ + template Vector3 Vector3::operator-() const { return Vector3(-x, -y, -z); } + /*! + * \brief Adds the components of the vector with other vector + * \return A vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector3 Vector3::operator+(const Vector3& vec) const { return Vector3(x + vec.x, y + vec.y, z + vec.z); } + /*! + * \brief Substracts the components of the vector with other vector + * \return A vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector3 Vector3::operator-(const Vector3& vec) const { return Vector3(x - vec.x, y - vec.y, z - vec.z); } + /*! + * \brief Multiplies the components of the vector with other vector + * \return A vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector3 Vector3::operator*(const Vector3& vec) const { return Vector3(x * vec.x, y * vec.y, z * vec.z); } + /*! + * \brief Multiplies the components of the vector with a scalar + * \return A vector where components are the product of this vector and the scalar + * + * \param scale The scalar to multiply components with + */ + template Vector3 Vector3::operator*(T scale) const { return Vector3(x * scale, y * scale, z * scale); } + /*! + * \brief Divides the components of the vector with other vector + * \return A vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector3 Vector3::operator/(const Vector3& vec) const { @@ -402,6 +781,16 @@ namespace Nz return Vector3(x / vec.x, y / vec.y, z / vec.z); } + /*! + * \brief Divides the components of the vector with a scalar + * \return A vector where components are the quotient of this vector and the scalar + * + * \param scale The scalar to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector3 Vector3::operator/(T scale) const { @@ -418,6 +807,13 @@ namespace Nz return Vector3(x / scale, y / scale, z / scale); } + /*! + * \brief Adds the components of other vector to this vector + * \return A reference to this vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector3& Vector3::operator+=(const Vector3& vec) { @@ -428,6 +824,13 @@ namespace Nz return *this; } + /*! + * \brief Substracts the components of other vector to this vector + * \return A reference to this vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector3& Vector3::operator-=(const Vector3& vec) { @@ -438,6 +841,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector3& Vector3::operator*=(const Vector3& vec) { @@ -448,6 +858,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector with a scalar + * \return A reference to this vector where components are the product of this vector and the scalar + * + * \param vec The other vector to multiply components with + */ + template Vector3& Vector3::operator*=(T scale) { @@ -458,6 +875,16 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to multiply components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector3& Vector3::operator/=(const Vector3& vec) { @@ -476,6 +903,16 @@ namespace Nz return *this; } + /*! + * \brief Divides the components of other vector with a scalar + * \return A reference to this vector where components are the quotient of this vector and the scalar + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector3& Vector3::operator/=(T scale) { @@ -494,20 +931,41 @@ namespace Nz return *this; } + /*! + * \brief Compares the vector to other one + * \return true if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator==(const Vector3& vec) const { return NumberEquals(x, vec.x) && - NumberEquals(y, vec.y) && - NumberEquals(z, vec.z); + NumberEquals(y, vec.y) && + NumberEquals(z, vec.z); } + /*! + * \brief Compares the vector to other one + * \return false if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator!=(const Vector3& vec) const { return !operator==(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator<(const Vector3& vec) const { @@ -522,6 +980,13 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator<=(const Vector3& vec) const { @@ -536,30 +1001,71 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator>(const Vector3& vec) const { return !operator<=(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector3::operator>=(const Vector3& vec) const { return !operator<(vec); } + /*! + * \brief Calculates the cross product with two vectors + * \return A vector which is the cross product according to "right-hand" rule + * + * \param vec1 The first vector to calculate the cross product with + * \param vec2 The second vector to calculate the cross product with + * + * \see CrossProduct + */ + template Vector3 Vector3::CrossProduct(const Vector3& vec1, const Vector3& vec2) { return vec1.CrossProduct(vec2); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec1 The first vector to calculate the dot product with + * \param vec2 The second vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector3::DotProduct(const Vector3& vec1, const Vector3& vec2) { return vec1.DotProduct(vec2); } + /*! + * \brief Shorthand for the vector (0, 0, 1) + * \return A vector with components (0, 0, 1) + * + * \see MakeBackward + */ + template Vector3 Vector3::Backward() { @@ -569,6 +1075,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, -1, 0) + * \return A vector with components (0, -1, 0) + * + * \see MakeDown + */ + template Vector3 Vector3::Down() { @@ -578,6 +1091,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, -1) + * \return A vector with components (0, 0, -1) + * + * \see Forward + */ + template Vector3 Vector3::Forward() { @@ -587,6 +1107,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (-1, 0, 0) + * \return A vector with components (-1, 0, 0) + * + * \see MakeLeft + */ + template Vector3 Vector3::Left() { @@ -596,18 +1123,54 @@ namespace Nz return vector; } + /*! + * \brief Interpolates the vector to other one with a factor of interpolation + * \return A new vector which is the interpolation of two vectors + * + * \param from Initial vector + * \param to Target vector + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * + * \see Lerp + */ + template Vector3 Vector3::Lerp(const Vector3& from, const Vector3& to, T interpolation) { - return Nz::Lerp(from, to, interpolation); + Vector3 dummy; + dummy.x = Nz::Lerp(from.x, to.x, interpolation); + dummy.y = Nz::Lerp(from.y, to.y, interpolation); + dummy.z = Nz::Lerp(from.z, to.z, interpolation); + + return dummy; } + /*! + * \brief Gives the normalized vector + * \return A normalized vector from the vec + * + * \param vec Vector to normalize + * + * \remark If the vector is (0, 0, 0), then it returns (0, 0, 0) + * + * \see GetNormal + */ + template Vector3 Vector3::Normalize(const Vector3& vec) { return vec.GetNormal(); } + /*! + * \brief Shorthand for the vector (1, 0, 0) + * \return A vector with components (1, 0, 0) + * + * \see MakeRight + */ + template Vector3 Vector3::Right() { @@ -617,6 +1180,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (1, 1, 1) + * \return A vector with components (1, 1, 1) + * + * \see MakeUnit + */ + template Vector3 Vector3::Unit() { @@ -626,6 +1196,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (1, 0, 0) + * \return A vector with components (1, 0, 0) + * + * \see MakeUnitX + */ + template Vector3 Vector3::UnitX() { @@ -635,6 +1212,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1, 0) + * \return A vector with components (0, 1, 0) + * + * \see MakeUnitY + */ + template Vector3 Vector3::UnitY() { @@ -644,6 +1228,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, 1) + * \return A vector with components (0, 0, 1) + * + * \see MakeUnitZ + */ + template Vector3 Vector3::UnitZ() { @@ -653,6 +1244,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1, 0) + * \return A vector with components (0, 1, 0) + * + * \see MakeUp + */ + template Vector3 Vector3::Up() { @@ -662,6 +1260,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, 0) + * \return A vector with components (0, 0, 0) + * + * \see MakeZero + */ + template Vector3 Vector3::Zero() { @@ -672,18 +1277,43 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param vec The vector to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec) { return out << vec.ToString(); } +/*! +* \brief Multiplies the components of the vector with a scalar +* \return A vector where components are the product of this vector and the scalar +* +* \param scale The scalar to multiply components with +*/ + template Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) { return Nz::Vector3(scale * vec.x, scale * vec.y, scale * vec.z); } +/*! +* \brief Divides the components of the vector with a scalar +* \return A vector where components are the quotient of this vector and the scalar +* +* \param scale The scalar to divide components with +* +* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined +* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null +*/ + template Nz::Vector3 operator/(T scale, const Nz::Vector3& vec) { From 139c49596635aeb4205e45507e7ff790245a5dc2 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:36:38 +0100 Subject: [PATCH 041/229] Documentation for Vector4 + static DotProduct & Normalize Former-commit-id: 4a190589292f299d266e20f7b9723594f2c32468 --- include/Nazara/Math/Vector4.hpp | 7 +- include/Nazara/Math/Vector4.inl | 507 +++++++++++++++++++++++++++++++- 2 files changed, 505 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index ac953f6ab..319f18e3b 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -60,8 +60,8 @@ namespace Nz String ToString() const; - operator T*(); - operator const T*() const; + operator T* (); + operator const T* () const; const Vector4& operator+() const; Vector4 operator-() const; @@ -87,6 +87,9 @@ namespace Nz bool operator>(const Vector4& vec) const; bool operator>=(const Vector4& vec) const; + static T DotProduct(const Vector4& vec1, const Vector4& vec2); + static Vector4 Lerp(const Vector4& from, const Vector4& to, T interpolation); + static Vector4 Normalize(const Vector4& vec); static Vector4 UnitX(); static Vector4 UnitY(); static Vector4 UnitZ(); diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 9193d6f06..c5127b34e 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -14,54 +14,125 @@ namespace Nz { + + /*! + * \class Nz::Vector4 + * \brief Math class that represents an element of the three dimensional vector space with the notion of projectivity. When the fourth component is 1, it describes an 'usual' point and when it is 0, it represents the point at infinity + */ + + /*! + * \brief Constructs a Vector4 object from its coordinates + * + * \param X X component + * \param Y Y component + * \param Z Z component + * \param W W component + */ + template Vector4::Vector4(T X, T Y, T Z, T W) { Set(X, Y, Z, W); } + /*! + * \brief Constructs a Vector4 object from two components and a Vector2 + * + * \param X X component + * \param Y Y component + * \param vec vec.X = Z component and vec.y = W component + */ + template Vector4::Vector4(T X, T Y, const Vector2& vec) { Set(X, Y, vec); } + /*! + * \brief Constructs a Vector4 object from one component, a Vector2 and one component + * + * \param X X component + * \param vec vec.X = Y component and vec.y = Z component + * \param W W component + */ + template Vector4::Vector4(T X, const Vector2& vec, T W) { Set(X, vec, W); } + /*! + * \brief Constructs a Vector4 object from one component and a Vector3 + * + * \param X X component + * \param vec vec.X = Y component, vec.y = Z component and vec.z = W component + */ + template Vector4::Vector4(T X, const Vector3& vec) { Set(X, vec); } + /*! + * \brief Constructs explicitely a Vector4 object from its "scale" + * + * \param scale X component = Y component = Z component = W component + */ + template Vector4::Vector4(T scale) { Set(scale); } + /*! + * \brief Constructs a Vector4 object from an array of four elements + * + * \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component + */ + template Vector4::Vector4(const T vec[4]) { Set(vec); } + /*! + * \brief Constructs a Vector4 object from a Vector2 and two components + * + * \param vec vec.X = X component and vec.y = Y component + * \param Z Z component + * \param W W component + */ + template Vector4::Vector4(const Vector2& vec, T Z, T W) { Set(vec, Z, W); } + /*! + * \brief Constructs a Vector4 object from one component and a Vector3 + * + * \param vec vec.X = X component, vec.y = Y component and vec.z = Z component + * \param W W component + */ + template Vector4::Vector4(const Vector3& vec, T W) { Set(vec, W); } + /*! + * \brief Constructs a Vector4 object from another type of Vector4 + * + * \param vec Vector of type U to convert to type T + */ + template template Vector4::Vector4(const Vector4& vec) @@ -69,18 +140,45 @@ namespace Nz Set(vec); } + /*! + * \brief Calculates the absolute dot (scalar) product with two vectors + * \return The dot product with absolutes values on each component + * + * \param vec The other vector to calculate the absolute dot product with + * + * \see DotProduct + */ + template T Vector4::AbsDotProduct(const Vector4& vec) const { return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z) + std::abs(w * vec.w); } + /*! + * \brief Calculates the dot (scalar) product with two vectors + * \return The value of the dot product + * + * \param vec The other vector to calculate the dot product with + * + * \see AbsDotProduct, DotProduct + */ + template T Vector4::DotProduct(const Vector4& vec) const { return x*vec.x + y*vec.y + z*vec.z + w*vec.w; } + /*! + * \brief Gets a copy normalized of the vector + * \return A new vector which is the vector normalized + * + * \param length Optional argument to obtain the length's ratio of the vector and the unit-length in this case w + * + * \see Normalize + */ + template Vector4 Vector4::GetNormal(T* length) const { @@ -90,30 +188,67 @@ namespace Nz return vec; } + /*! + * \brief Makes the vector (1, 0, 0, 1) + * \return A reference to this vector with components (1, 0, 0, 1) + * + * \see UnitX + */ + template Vector4& Vector4::MakeUnitX() { return Set(F(1.0), F(0.0), F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 1, 0, 1) + * \return A reference to this vector with components (0, 1, 0, 1) + * + * \see UnitY + */ + template Vector4& Vector4::MakeUnitY() { return Set(F(0.0), F(1.0), F(0.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 0, 1, 1) + * \return A reference to this vector with components (0, 0, 1, 1) + * + * \see UnitZ + */ + template Vector4& Vector4::MakeUnitZ() { return Set(F(0.0), F(0.0), F(1.0), F(1.0)); } + /*! + * \brief Makes the vector (0, 0, 0, 1) + * \return A reference to this vector with components (0, 0, 0, 1) + * + * \see Zero + */ + template Vector4& Vector4::MakeZero() { - return Set(F(0.0), F(0.0), F(0.0), F(0.0)); + return Set(F(0.0), F(0.0), F(0.0), F(1.0)); } + /*! + * \brief Sets this vector's components to the maximum of its own and other components + * \return A reference to this vector with replaced values with the corresponding max value + * + * \param vec Other vector to compare the components with + * + * \see Minimize + */ + template Vector4& Vector4::Maximize(const Vector4& vec) { @@ -132,6 +267,15 @@ namespace Nz return *this; } + /*! + * \brief Sets this vector's components to the minimum of its own and other components + * \return A reference to this vector with replaced values with the corresponding min value + * + * \param vec Other vector to compare the components with + * + * \see Maximize + */ + template Vector4& Vector4::Minimize(const Vector4& vec) { @@ -150,11 +294,20 @@ namespace Nz return *this; } + /*! + * \brief Gives the normalized vector + * \return A normalized vector from the vec with w = 1 + * + * \param length Optional argument to obtain the length's ratio of the vector in this case w + * + * \see GetNormal + */ + template Vector4& Vector4::Normalize(T* length) { T invLength = F(1.0)/w; - x *= invLength; // Attention, briser cette logique casserait Frustum::Extract + x *= invLength; // Warning, change this logic will break Frustum::Extract y *= invLength; z *= invLength; @@ -166,6 +319,16 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector + * \return A reference to this vector + * + * \param X X component + * \param Y Y component + * \param Z Z component + * \param W W component + */ + template Vector4& Vector4::Set(T X, T Y, T Z, T W) { @@ -177,6 +340,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from two components and a Vector2 + * \return A reference to this vector + * + * \param X X component + * \param Y Y component + * \param vec vec.X = Z component and vec.y = W component + */ + template Vector4& Vector4::Set(T X, T Y, const Vector2& vec) { @@ -188,6 +360,15 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from one component, a Vector2 and one component + * \return A reference to this vector + * + * \param X X component + * \param vec vec.X = Y component and vec.y = Z component + * \param W W component + */ + template Vector4& Vector4::Set(T X, const Vector2& vec, T W) { @@ -199,6 +380,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from one component and a Vector3 + * \return A reference to this vector + * + * \param X X component + * \param vec vec.X = Y component, vec.y = Z component and vec.z = W component + */ + template Vector4& Vector4::Set(T X, const Vector3& vec) { @@ -210,6 +399,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a "scale" + * \return A reference to this vector + * + * \param scale X component = Y component = Z component = W component + */ + template Vector4& Vector4::Set(T scale) { @@ -221,6 +417,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from an array of four elements + * \return A reference to this vector + * + * \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component + */ + template Vector4& Vector4::Set(const T vec[4]) { @@ -229,6 +432,14 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector2 and two components + * + * \param vec vec.X = X component and vec.y = Y component + * \param Z Z component + * \param W W component + */ + template Vector4& Vector4::Set(const Vector2& vec, T Z, T W) { @@ -240,6 +451,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from a Vector3 and one components + * + * \param vec vec.X = X component, vec.y = Y component and vec.z = Z component + * \param W W component + */ + template Vector4& Vector4::Set(const Vector3& vec, T W) { @@ -251,6 +469,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another vector + * \return A reference to this vector + * + * \param vec The other vector + */ + template Vector4& Vector4::Set(const Vector4& vec) { @@ -259,6 +484,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the components of the vector from another type of Vector4 + * \return A reference to this vector + * + * \param vec Vector of type U to convert its components + */ + template template Vector4& Vector4::Set(const Vector4& vec) @@ -271,6 +503,11 @@ namespace Nz return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "Vector4(x, y, z, w)" + */ + template String Vector4::ToString() const { @@ -279,54 +516,116 @@ namespace Nz return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')'; } + /*! + * \brief Converts vector to pointer to its own data + * \return A pointer to the own data + * + * \remark Access to index greather than 3 is undefined behavior + */ + template - Vector4::operator T*() + Vector4::operator T* () { return &x; } + /*! + * \brief Converts vector to const pointer to its own data + * \return A constant pointer to the own data + * + * \remark Access to index greather than 3 is undefined behavior + */ + template - Vector4::operator const T*() const + Vector4::operator const T* () const { return &x; } + /*! + * \brief Helps to represent the sign of the vector + * \return A constant reference to this vector + */ + template const Vector4& Vector4::operator+() const { return *this; } + /*! + * \brief Negates the components of the vector + * \return A constant reference to this vector with negate components + */ + template Vector4 Vector4::operator-() const { return Vector4(-x, -y, -z, -w); } + /*! + * \brief Adds the components of the vector with other vector + * \return A vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector4 Vector4::operator+(const Vector4& vec) const { return Vector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w); } + /*! + * \brief Substracts the components of the vector with other vector + * \return A vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector4 Vector4::operator-(const Vector4& vec) const { return Vector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w); } + /*! + * \brief Multiplies the components of the vector with other vector + * \return A vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector4 Vector4::operator*(const Vector4& vec) const { return Vector4(x * vec.x, y * vec.y, z * vec.z, w * vec.w); } + /*! + * \brief Multiplies the components of the vector with a scalar + * \return A vector where components are the product of this vector and the scalar + * + * \param scale The scalar to multiply components with + */ + template Vector4 Vector4::operator*(T scale) const { return Vector4(x * scale, y * scale, z * scale, w * scale); } + /*! + * \brief Divides the components of the vector with other vector + * \return A vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector4 Vector4::operator/(const Vector4& vec) const { @@ -343,6 +642,16 @@ namespace Nz return Vector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w); } + /*! + * \brief Divides the components of the vector with a scalar + * \return A vector where components are the quotient of this vector and the scalar + * + * \param scale The scalar to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector4 Vector4::operator/(T scale) const { @@ -359,6 +668,13 @@ namespace Nz return Vector4(x / scale, y / scale, z / scale, w / scale); } + /*! + * \brief Adds the components of other vector to this vector + * \return A reference to this vector where components are the sum of this vector and the other one + * + * \param vec The other vector to add components with + */ + template Vector4& Vector4::operator+=(const Vector4& vec) { @@ -370,6 +686,13 @@ namespace Nz return *this; } + /*! + * \brief Substracts the components of other vector to this vector + * \return A reference to this vector where components are the difference of this vector and the other one + * + * \param vec The other vector to substract components with + */ + template Vector4& Vector4::operator-=(const Vector4& vec) { @@ -381,6 +704,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the product of this vector and the other one + * + * \param vec The other vector to multiply components with + */ + template Vector4& Vector4::operator*=(const Vector4& vec) { @@ -392,6 +722,13 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector with a scalar + * \return A reference to this vector where components are the product of this vector and the scalar + * + * \param vec The other vector to multiply components with + */ + template Vector4& Vector4::operator*=(T scale) { @@ -403,6 +740,16 @@ namespace Nz return *this; } + /*! + * \brief Multiplies the components of other vector to this vector + * \return A reference to this vector where components are the quotient of this vector and the other one + * + * \param vec The other vector to multiply components with + * + * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null + */ + template Vector4& Vector4::operator/=(const Vector4& vec) { @@ -424,6 +771,16 @@ namespace Nz return *this; } + /*! + * \brief Divides the components of other vector with a scalar + * \return A reference to this vector where components are the quotient of this vector and the scalar + * + * \param vec The other vector to divide components with + * + * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined + * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null + */ + template Vector4& Vector4::operator/=(T scale) { @@ -445,21 +802,42 @@ namespace Nz return *this; } + /*! + * \brief Compares the vector to other one + * \return true if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector4::operator==(const Vector4& vec) const { return NumberEquals(x, vec.x) && - NumberEquals(y, vec.y) && - NumberEquals(z, vec.z) && - NumberEquals(w, vec.w); + NumberEquals(y, vec.y) && + NumberEquals(z, vec.z) && + NumberEquals(w, vec.w); } + /*! + * \brief Compares the vector to other one + * \return false if the vectors are the same + * + * \param vec Other vector to compare with + */ + template bool Vector4::operator!=(const Vector4& vec) const { return !operator==(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector4::operator<(const Vector4& vec) const { @@ -479,6 +857,13 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components inferior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector4::operator<=(const Vector4& vec) const { @@ -498,18 +883,79 @@ namespace Nz return x < vec.x; } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector4::operator>(const Vector4& vec) const { return !operator<=(vec); } + /*! + * \brief Compares the vector to other one + * \return true if this vector has its first components superior or equal to the other ones + * + * \param vec Other vector to compare with + */ + template bool Vector4::operator>=(const Vector4& vec) const { return !operator<(vec); } + /*! + * \brief Interpolates the vector to other one with a factor of interpolation + * \return A new vector which is the interpolation of two vectors + * + * \param from Initial vector + * \param to Target vector + * \param interpolation Factor of interpolation + * + * \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior + * + * \see Lerp + */ + + template + Vector4 Vector4::Lerp(const Vector4& from, const Vector4& to, T interpolation) + { + Vector4 dummy; + dummy.x = Nz::Lerp(from.x, to.x, interpolation); + dummy.y = Nz::Lerp(from.y, to.y, interpolation); + dummy.z = Nz::Lerp(from.z, to.z, interpolation); + dummy.w = Nz::Lerp(from.w, to.w, interpolation); + + return dummy; + } + + /*! + * \brief Gives the normalized vector + * \return A normalized vector from the vec with w = 1 + * + * \param vec Vector to normalize + * + * \see GetNormal + */ + + template + Vector4 Vector4::Normalize(const Vector4& vec) + { + return vec.GetNormal(); + } + + /*! + * \brief Shorthand for the vector (1, 0, 0, 1) + * \return A vector with components (1, 0, 0, 1) + * + * \see MakeUnitX + */ + template Vector4 Vector4::UnitX() { @@ -519,6 +965,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 1, 0, 1) + * \return A vector with components (0, 1, 0, 1) + * + * \see MakeUnitY + */ + template Vector4 Vector4::UnitY() { @@ -528,6 +981,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, 1, 1) + * \return A vector with components (0, 0, 1, 1) + * + * \see MakeUnitZ + */ + template Vector4 Vector4::UnitZ() { @@ -537,6 +997,13 @@ namespace Nz return vector; } + /*! + * \brief Shorthand for the vector (0, 0, 0, 1) + * \return A vector with components (0, 0, 0, 1) + * + * \see MakeZero + */ + template Vector4 Vector4::Zero() { @@ -547,18 +1014,44 @@ namespace Nz } } +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param vec The vector to output +*/ + template std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec) { return out << vec.ToString(); } +/*! +* \brief Multiplies the components of the vector with a scalar +* \return A vector where components are the product of this vector and the scalar +* +* \param scale The scalar to multiply components with +*/ + + template Nz::Vector4 operator*(T scale, const Nz::Vector4& vec) { return Nz::Vector4(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w); } +/*! +* \brief Divides the components of the vector with a scalar +* \return A vector where components are the quotient of this vector and the scalar +* +* \param scale The scalar to divide components with +* +* \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined +* \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null +*/ + template Nz::Vector4 operator/(T scale, const Nz::Vector4& vec) { From 15e4fe14534bf99bb22c4720d482333db588f577 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:38:52 +0100 Subject: [PATCH 042/229] New tests ! Former-commit-id: 1cb5949ce7b9fde74189a37c75f0b3380fda95c7 --- tests/Engine/Math/Algorithm.cpp | 83 ++++++++++++++++++++++++---- tests/Engine/Math/BoundingVolume.cpp | 15 +++++ tests/Engine/Math/Box.cpp | 12 ++++ tests/Engine/Math/EulerAngles.cpp | 25 ++++++++- tests/Engine/Math/Frustum.cpp | 13 +++++ tests/Engine/Math/Matrix4.cpp | 40 +++++++++----- tests/Engine/Math/OrientedBox.cpp | 15 +++++ tests/Engine/Math/Plane.cpp | 12 ++++ tests/Engine/Math/Quaternion.cpp | 29 ++++++++++ tests/Engine/Math/Ray.cpp | 29 +++++++++- tests/Engine/Math/Rect.cpp | 12 ++++ tests/Engine/Math/Sphere.cpp | 40 ++++++++++++++ tests/Engine/Math/Vector2.cpp | 51 ++++++++++++++++- tests/Engine/Math/Vector3.cpp | 46 ++++++++++++++- tests/Engine/Math/Vector4.cpp | 10 ++++ 15 files changed, 399 insertions(+), 33 deletions(-) diff --git a/tests/Engine/Math/Algorithm.cpp b/tests/Engine/Math/Algorithm.cpp index 38080c576..c42b90d11 100644 --- a/tests/Engine/Math/Algorithm.cpp +++ b/tests/Engine/Math/Algorithm.cpp @@ -1,7 +1,7 @@ #include #include -TEST_CASE("Approach", "[MATH][ALGORITHM]" ) +TEST_CASE("Approach", "[MATH][ALGORITHM]") { SECTION("Approach 8 with 5 by 2") { @@ -19,7 +19,7 @@ TEST_CASE("Approach", "[MATH][ALGORITHM]" ) } } -TEST_CASE("Clamp", "[ALGORITHM]" ) +TEST_CASE("Clamp", "[ALGORITHM]") { SECTION("Clamp 8 between 5 and 10") { @@ -37,7 +37,20 @@ TEST_CASE("Clamp", "[ALGORITHM]" ) } } -TEST_CASE("DegreeToRadian", "[ALGORITHM]" ) +TEST_CASE("CountBits", "[ALGORITHM]") +{ + SECTION("Number 10 has 2 bits set to 1") + { + REQUIRE(Nz::CountBits(10) == 2); + } + + SECTION("Number 0 has 0 bit set to 1") + { + REQUIRE(Nz::CountBits(0) == 0); + } +} + +TEST_CASE("DegreeToRadian", "[ALGORITHM]") { SECTION("Convert 45.f degree to radian") { @@ -45,8 +58,13 @@ TEST_CASE("DegreeToRadian", "[ALGORITHM]" ) } } -TEST_CASE("GetNearestPowerOfTwo", "[ALGORITHM]" ) +TEST_CASE("GetNearestPowerOfTwo", "[ALGORITHM]") { + SECTION("Nearest power of two of 0 = 1") + { + REQUIRE(Nz::GetNearestPowerOfTwo(0) == 1); + } + SECTION("Nearest power of two of 16 = 16") { REQUIRE(Nz::GetNearestPowerOfTwo(16) == 16); @@ -58,7 +76,7 @@ TEST_CASE("GetNearestPowerOfTwo", "[ALGORITHM]" ) } } -TEST_CASE("GetNumberLength", "[ALGORITHM]" ) +TEST_CASE("GetNumberLength", "[ALGORITHM]") { SECTION("GetNumberLength of -127 signed char") { @@ -115,7 +133,48 @@ TEST_CASE("GetNumberLength", "[ALGORITHM]" ) } } -TEST_CASE("IntegralPow", "[ALGORITHM]" ) +TEST_CASE("IntegralLog2", "[ALGORITHM]") +{ + SECTION("According to implementation, log in base 2 of 0 = 0") + { + REQUIRE(Nz::IntegralLog2(0) == 0); + } + + SECTION("Log in base 2 of 1 = 0") + { + REQUIRE(Nz::IntegralLog2(1) == 0); + } + + SECTION("Log in base 2 of 4 = 2") + { + REQUIRE(Nz::IntegralLog2(4) == 2); + } + + SECTION("Log in base 2 of 5 = 2") + { + REQUIRE(Nz::IntegralLog2(5) == 2); + } +} + +TEST_CASE("IntegralLog2Pot", "[ALGORITHM]") +{ + SECTION("According to implementation, log in base 2 of 0 = 0") + { + REQUIRE(Nz::IntegralLog2Pot(0) == 0); + } + + SECTION("Log in base 2 of 1 = 0") + { + REQUIRE(Nz::IntegralLog2Pot(1) == 0); + } + + SECTION("Log in base 2 of 4 = 2") + { + REQUIRE(Nz::IntegralLog2Pot(4) == 2); + } +} + +TEST_CASE("IntegralPow", "[ALGORITHM]") { SECTION("2 to power 4") { @@ -123,7 +182,7 @@ TEST_CASE("IntegralPow", "[ALGORITHM]" ) } } -TEST_CASE("Lerp", "[ALGORITHM]" ) +TEST_CASE("Lerp", "[ALGORITHM]") { SECTION("Lerp 2 to 6 with 0.5") { @@ -131,7 +190,7 @@ TEST_CASE("Lerp", "[ALGORITHM]" ) } } -TEST_CASE("MultiplyAdd", "[ALGORITHM]" ) +TEST_CASE("MultiplyAdd", "[ALGORITHM]") { SECTION("2 * 3 + 1") { @@ -139,7 +198,7 @@ TEST_CASE("MultiplyAdd", "[ALGORITHM]" ) } } -TEST_CASE("NumberEquals", "[ALGORITHM]" ) +TEST_CASE("NumberEquals", "[ALGORITHM]") { SECTION("2.35 and 2.351 should be the same at 0.01") { @@ -152,7 +211,7 @@ TEST_CASE("NumberEquals", "[ALGORITHM]" ) } } -TEST_CASE("NumberToString", "[ALGORITHM]" ) +TEST_CASE("NumberToString", "[ALGORITHM]") { SECTION("235 to string") { @@ -170,7 +229,7 @@ TEST_CASE("NumberToString", "[ALGORITHM]" ) } } -TEST_CASE("RadianToDegree", "[ALGORITHM]" ) +TEST_CASE("RadianToDegree", "[ALGORITHM]") { SECTION("PI / 4 to degree") { @@ -178,7 +237,7 @@ TEST_CASE("RadianToDegree", "[ALGORITHM]" ) } } -TEST_CASE("StringToNumber", "[ALGORITHM]" ) +TEST_CASE("StringToNumber", "[ALGORITHM]") { SECTION("235 in string") { diff --git a/tests/Engine/Math/BoundingVolume.cpp b/tests/Engine/Math/BoundingVolume.cpp index 05af375bc..9fd552863 100644 --- a/tests/Engine/Math/BoundingVolume.cpp +++ b/tests/Engine/Math/BoundingVolume.cpp @@ -99,5 +99,20 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]") REQUIRE(firstCenterAndUnit.aabb != secondCenterAndUnit.aabb); } } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::BoundingVolumef nullBoundingVolume = Nz::BoundingVolumef(Nz::Vector3f::Zero(), Nz::Vector3f::Zero()); + Nz::BoundingVolumef centerAndUnit = firstCenterAndUnit; + nullBoundingVolume.Update(Nz::Matrix4f::Identity()); + centerAndUnit.Update(Nz::Matrix4f::Identity()); + Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + result.Update(Nz::Matrix4f::Identity()); + + REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result); + } + } } } diff --git a/tests/Engine/Math/Box.cpp b/tests/Engine/Math/Box.cpp index e39e0654c..7d9b42a51 100644 --- a/tests/Engine/Math/Box.cpp +++ b/tests/Engine/Math/Box.cpp @@ -64,6 +64,18 @@ SCENARIO("Box", "[MATH][BOX]") REQUIRE(tmp == firstCenterAndUnit); } } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Boxf nullBox = Nz::Boxf::Zero(); + Nz::Boxf centerAndUnit = firstCenterAndUnit; + Nz::Boxf result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + + REQUIRE(Nz::Boxf::Lerp(nullBox, centerAndUnit, 0.5f) == result); + } + } } GIVEN("Two wrong box (negative width, height and depth") diff --git a/tests/Engine/Math/EulerAngles.cpp b/tests/Engine/Math/EulerAngles.cpp index a44efb361..6a6f7f77e 100644 --- a/tests/Engine/Math/EulerAngles.cpp +++ b/tests/Engine/Math/EulerAngles.cpp @@ -15,8 +15,8 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]") WHEN("We do some operations") { - Nz::EulerAnglesf euler90(90.f, 90.f, 90.f); - Nz::EulerAnglesf euler270(270.f, 270.f, 270.f); + Nz::EulerAnglesf euler90(Nz::FromDegrees(90.f), Nz::FromDegrees(90.f), Nz::FromDegrees(90.f)); + Nz::EulerAnglesf euler270(Nz::FromDegrees(270.f), Nz::FromDegrees(270.f), Nz::FromDegrees(270.f)); Nz::EulerAnglesf euler360 = euler90 + euler270; euler360.Normalize(); @@ -42,6 +42,27 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]") } } + GIVEN("Three rotation of 90 on each axis") + { + Nz::EulerAnglesf euler90P(Nz::FromDegrees(90.f), 0.f, 0.f); + Nz::EulerAnglesf euler90Y(0.f, Nz::FromDegrees(90.f), 0.f); + Nz::EulerAnglesf euler90R(0.f, 0.f, Nz::FromDegrees(90.f)); + + WHEN("We transform the axis") + { + THEN("This is supposed to be left-handed") + { + Nz::Vector3f rotation90P = euler90P.ToQuaternion() * Nz::Vector3f::UnitY(); + Nz::Vector3f rotation90Y = euler90Y.ToQuaternion() * Nz::Vector3f::UnitZ(); + Nz::Vector3f rotation90R = euler90R.ToQuaternion() * Nz::Vector3f::UnitX(); + + REQUIRE(rotation90P == Nz::Vector3f::UnitZ()); + REQUIRE(rotation90Y == Nz::Vector3f::UnitX()); + REQUIRE(rotation90R == Nz::Vector3f::UnitY()); + } + } + } + GIVEN("Euler angles with rotation 45 on each axis") { WHEN("We convert to quaternion") diff --git a/tests/Engine/Math/Frustum.cpp b/tests/Engine/Math/Frustum.cpp index 98715940d..d9fedebdd 100644 --- a/tests/Engine/Math/Frustum.cpp +++ b/tests/Engine/Math/Frustum.cpp @@ -78,5 +78,18 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]") CHECK(frustum.Contains(&tmp, 1)); } } + + WHEN("We test for edge cases") + { + THEN("Implementation defined these") + { + Nz::BoundingVolumef nullVolume = Nz::BoundingVolumef::Null(); + CHECK(!frustum.Contains(nullVolume)); + Nz::BoundingVolumef infiniteVolume = Nz::BoundingVolumef::Infinite(); + CHECK(frustum.Contains(infiniteVolume)); + REQUIRE(frustum.Intersect(nullVolume) == Nz::IntersectionSide_Outside); + REQUIRE(frustum.Intersect(infiniteVolume) == Nz::IntersectionSide_Intersecting); + } + } } } diff --git a/tests/Engine/Math/Matrix4.cpp b/tests/Engine/Math/Matrix4.cpp index 24a56658b..eec10aacd 100644 --- a/tests/Engine/Math/Matrix4.cpp +++ b/tests/Engine/Math/Matrix4.cpp @@ -37,19 +37,29 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") REQUIRE(firstIdentity.Inverse() == secondIdentity.InverseAffine()); } } + + WHEN("We transpose one of this matrix") + { + THEN("Identity transposed is the same than identity") + { + Nz::Matrix4f transposedIdentity; + firstIdentity.GetTransposed(&transposedIdentity); + REQUIRE(firstIdentity == transposedIdentity); + } + } } GIVEN("Two different matrix") { Nz::Matrix4f matrix1(1.0f, 0.0f, 0.0f, 0.0f, - 7.0f, 2.0f, 0.0f, 0.0f, - 1.0f, 5.0f, 3.0f, 0.0f, - 8.0f, 9.0f, 2.0f, 4.0f); + 7.0f, 2.0f, 0.0f, 0.0f, + 1.0f, 5.0f, 3.0f, 0.0f, + 8.0f, 9.0f, 2.0f, 4.0f); Nz::Matrix4f matrix2(1.0f, 1.0f, 2.0f, -1.0f, - -2.0f, -1.0f, -2.0f, 2.0f, - 4.0f, 2.0f, 5.0f, -4.0f, - 5.0f, -3.0f, -7.0f, -6.0f); + -2.0f, -1.0f, -2.0f, 2.0f, + 4.0f, 2.0f, 5.0f, -4.0f, + 5.0f, -3.0f, -7.0f, -6.0f); WHEN("We ask for determinant") { @@ -92,9 +102,9 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { transformedMatrix.MakeTransform(Nz::Vector3f::Zero(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion()); Nz::Matrix4f rotation45X(1.f, 0.f, 0.f, 0.f, - 0.f, std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, - 0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, - 0.f, 0.f, 0.f, 1.f); + 0.f, std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, + 0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, + 0.f, 0.f, 0.f, 1.f); REQUIRE(transformedMatrix == rotation45X); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion()); @@ -106,9 +116,9 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { transformedMatrix.MakeTransform(Nz::Vector3f::Zero(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion()); Nz::Matrix4f rotation45Y(std::sqrt(2.f) / 2.f, 0.f, -std::sqrt(2.f) / 2.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - std::sqrt(2.f) / 2.f, 0.f, std::sqrt(2.f) / 2.f, 0.f, - 0.f, 0.f, 0.f, 1.f); + 0.f, 1.f, 0.f, 0.f, + std::sqrt(2.f) / 2.f, 0.f, std::sqrt(2.f) / 2.f, 0.f, + 0.f, 0.f, 0.f, 1.f); REQUIRE(transformedMatrix == rotation45Y); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion()); @@ -120,9 +130,9 @@ SCENARIO("Matrix4", "[MATH][Matrix4]") { transformedMatrix.MakeTransform(Nz::Vector3f::Zero(), Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion()); Nz::Matrix4f rotation45Z( std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, - -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f); + -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f); REQUIRE(transformedMatrix == rotation45Z); transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion())); diff --git a/tests/Engine/Math/OrientedBox.cpp b/tests/Engine/Math/OrientedBox.cpp index bd11f58ef..7a1035ee2 100644 --- a/tests/Engine/Math/OrientedBox.cpp +++ b/tests/Engine/Math/OrientedBox.cpp @@ -43,5 +43,20 @@ SCENARIO("OrientedBox", "[MATH][ORIENTEDBOX]") } } } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::OrientedBoxf nullOrientedBox = Nz::OrientedBoxf::Zero(); + Nz::OrientedBoxf centerAndUnit = firstCenterAndUnit; + nullOrientedBox.Update(Nz::Matrix4f::Identity()); + centerAndUnit.Update(Nz::Matrix4f::Identity()); + Nz::OrientedBoxf result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f); + result.Update(Nz::Matrix4f::Identity()); + + REQUIRE(Nz::OrientedBoxf::Lerp(nullOrientedBox, centerAndUnit, 0.5f) == result); + } + } } } diff --git a/tests/Engine/Math/Plane.cpp b/tests/Engine/Math/Plane.cpp index 1cab6f385..44377bf67 100644 --- a/tests/Engine/Math/Plane.cpp +++ b/tests/Engine/Math/Plane.cpp @@ -49,6 +49,18 @@ SCENARIO("Plane", "[MATH][PLANE]") REQUIRE(Nz::Planef(-Nz::Vector3f::UnitY(), -1000.f).Distance(Nz::Vector3f::UnitY() * 1500.f) == Approx(-500.f)); } } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Planef planeXY = Nz::Planef::XY(); + Nz::Planef planeXZ = Nz::Planef::XZ(); + Nz::Vector3f result = Nz::Vector3f(0.f, 1.f, 1.f) * 0.5f; + result.Normalize(); + REQUIRE(Nz::Planef::Lerp(planeXY, planeXZ, 0.5f) == Nz::Planef(result, 0.f)); + } + } } GIVEN("The plane XZ, distance 1 with 3 points (0, 1, 0), (1, 1, 1), (-1, 1, 0)") diff --git a/tests/Engine/Math/Quaternion.cpp b/tests/Engine/Math/Quaternion.cpp index 65ab201bf..7ebf6ede5 100644 --- a/tests/Engine/Math/Quaternion.cpp +++ b/tests/Engine/Math/Quaternion.cpp @@ -32,6 +32,22 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") REQUIRE((firstQuaternion * Nz::Vector3f::UnitZ()) == -Nz::Vector3f::UnitZ()); } } + + WHEN("We invert or normalize Zero quaternion") + { + Nz::Quaternionf zero = Nz::Quaternionf::Zero(); + + THEN("It's meant not to be changed") + { + Nz::Quaternionf inverted = zero.GetInverse(); + float tmp = -1.f; + Nz::Quaternionf normalized = zero.GetNormal(&tmp); + + REQUIRE(inverted == zero); + REQUIRE(normalized == zero); + REQUIRE(tmp == Approx(0.f)); + } + } } GIVEN("The four unit quaternions") @@ -154,5 +170,18 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") REQUIRE(quaternionC.z == Approx(unitZ225.z)); } } + + WHEN("We get the rotation between two vectors") + { + /*TODO + * Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY()); + + THEN("The rotation in left-handed is 270 degree on z") + { + Nz::Quaternionf rotation270Z(Nz::FromDegrees(270.f), Nz::Vector3f::UnitZ()); + Nz::Quaternionf rotation90Z(Nz::FromDegrees(90.f), Nz::Vector3f::UnitZ()); + REQUIRE(rotation90Z == rotationBetweenXY); + }*/ + } } } diff --git a/tests/Engine/Math/Ray.cpp b/tests/Engine/Math/Ray.cpp index df77a34ac..286a358c2 100644 --- a/tests/Engine/Math/Ray.cpp +++ b/tests/Engine/Math/Ray.cpp @@ -86,10 +86,37 @@ SCENARIO("Ray", "[MATH][RAY]") Nz::BoundingVolumef nullVolume(Nz::Extend_Null); CHECK(!ray.Intersect(nullVolume)); + float tmpClosest = -1.f; + float tmpFurthest = -1.f; Nz::BoundingVolumef infiniteVolume(Nz::Extend_Infinite); - CHECK(ray.Intersect(infiniteVolume)); + CHECK(ray.Intersect(infiniteVolume, &tmpClosest, &tmpFurthest)); + CHECK(tmpClosest == Approx(0.f)); + CHECK(tmpFurthest == std::numeric_limits::infinity()); } + THEN("For the triangle collision's") + { + Nz::Vector3f firstPoint(0.f, 1.f, 1.f); + Nz::Vector3f secondPoint(-1.f, 1.f, -1.f); + Nz::Vector3f thidPoint(1.f, 1.f, -1.f); + float tmpHit = -1.f; + + CHECK(ray.Intersect(firstPoint, secondPoint, thidPoint, &tmpHit)); + REQUIRE(ray.GetPoint(tmpHit) == Nz::Vector3f::UnitY()); + + Nz::Vector3f offset = Nz::Vector3f(10.f, 0.f, 10.f); + CHECK(!ray.Intersect(firstPoint + offset, secondPoint + offset, thidPoint + offset, &tmpHit)); + } + } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Rayf AxisX = Nz::Rayf::AxisX(); + Nz::Rayf AxisY = Nz::Rayf::AxisY(); + REQUIRE(Nz::Rayf::Lerp(AxisX, AxisY, 0.5f) == (Nz::Rayf(Nz::Vector3f::Zero(), Nz::Vector3f(0.5f, 0.5f, 0.f)))); + } } } } diff --git a/tests/Engine/Math/Rect.cpp b/tests/Engine/Math/Rect.cpp index 7a1035f79..b119d76c9 100644 --- a/tests/Engine/Math/Rect.cpp +++ b/tests/Engine/Math/Rect.cpp @@ -52,5 +52,17 @@ SCENARIO("Rect", "[MATH][RECT]") } } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Rectf nullRect = Nz::Rectf::Zero(); + Nz::Rectf centerAndUnit = firstCenterAndUnit; + Nz::Rectf result(Nz::Vector2f::Zero(), Nz::Vector2f::Unit() * 0.5f); + + REQUIRE(Nz::Rectf::Lerp(nullRect, centerAndUnit, 0.5f) == result); + } + } } } diff --git a/tests/Engine/Math/Sphere.cpp b/tests/Engine/Math/Sphere.cpp index 0f0e509ca..1820acd35 100644 --- a/tests/Engine/Math/Sphere.cpp +++ b/tests/Engine/Math/Sphere.cpp @@ -59,5 +59,45 @@ SCENARIO("Sphere", "[MATH][SPHERE]") REQUIRE(centerUnitBox.GetSquaredBoundingSphere() == Nz::Spheref(Nz::Vector3f::Zero(), 0.75f)); } } + + WHEN("We ask for positive and negative vertex") + { + Nz::Vector3f positiveVector = Nz::Vector3f::UnitY(); + + THEN("Positive vertex should be the same with centered and unit sphere") + { + REQUIRE(positiveVector == firstCenterAndUnit.GetPositiveVertex(positiveVector)); + } + + AND_THEN("Negative vertex should be the opposite") + { + REQUIRE(-positiveVector == firstCenterAndUnit.GetNegativeVertex(positiveVector)); + } + } + + WHEN("We extend the unit sphere to one point") + { + Nz::Vector3f point = Nz::Vector3f::UnitY() * 2.f; + + firstCenterAndUnit.ExtendTo(point); + + THEN("Sphere must contain it and distance should be good") + { + CHECK(firstCenterAndUnit.Contains(point)); + REQUIRE(firstCenterAndUnit.Distance(point) == 2.f); + } + } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Spheref nullRect = Nz::Spheref::Zero(); + Nz::Spheref centerAndUnit = firstCenterAndUnit; + Nz::Spheref result(Nz::Vector3f::Zero(), 0.5f); + + REQUIRE(Nz::Spheref::Lerp(nullRect, centerAndUnit, 0.5f) == result); + } + } } } diff --git a/tests/Engine/Math/Vector2.cpp b/tests/Engine/Math/Vector2.cpp index 17ae62e72..45ca1468c 100644 --- a/tests/Engine/Math/Vector2.cpp +++ b/tests/Engine/Math/Vector2.cpp @@ -15,6 +15,7 @@ SCENARIO("Vector2", "[MATH][VECTOR2]") THEN("They are the same") { REQUIRE(firstUnit == secondUnit); + REQUIRE(firstUnit <= secondUnit); } } @@ -22,11 +23,13 @@ SCENARIO("Vector2", "[MATH][VECTOR2]") { Nz::Vector2f tmp(-1.f, 1.f); - THEN("These results are expected") + THEN("These are perpendicular") { REQUIRE(firstUnit.AbsDotProduct(tmp) == Approx(2.f)); REQUIRE(firstUnit.DotProduct(tmp) == Approx(0.f)); - REQUIRE(firstUnit.AngleBetween(tmp) == Approx(90.f)); + REQUIRE(firstUnit.AngleBetween(tmp) == Approx(Nz::FromDegrees(90.f))); + Nz::Vector2f negativeUnitX = -Nz::Vector2f::UnitX(); + REQUIRE(negativeUnitX.AngleBetween(negativeUnitX + Nz::Vector2f(0, 0.0000001f)) == Approx(Nz::FromDegrees(360.f))); } } @@ -45,5 +48,49 @@ SCENARIO("Vector2", "[MATH][VECTOR2]") REQUIRE(firstUnit.GetLength() == Approx(std::sqrt(2.f))); } } + + WHEN("We nomalize the vectors") + { + float ratio = 0.f; + THEN("For normal cases should be normal") + { + Nz::Vector2f normalized = firstUnit.GetNormal(&ratio); + REQUIRE(normalized == (Nz::Vector2f::Unit() / std::sqrt(2.f))); + REQUIRE(ratio == Approx(std::sqrt(2.f))); + } + + THEN("For null vector") + { + Nz::Vector2f zero = Nz::Vector2f::Zero(); + REQUIRE(zero.GetNormal(&ratio) == Nz::Vector2f::Zero()); + REQUIRE(ratio == Approx(0.f)); + } + } + + WHEN("We try to maximize and minimize") + { + Nz::Vector2f maximize(2.f, 1.f); + Nz::Vector2f minimize(1.f, 2.f); + + THEN("The minimised and maximised should be (1, 1) and (2, 2)") + { + Nz::Vector2f maximized = maximize; + Nz::Vector2f minimized = minimize; + REQUIRE(minimized.Minimize(maximized) == Nz::Vector2f::Unit()); + REQUIRE(maximize.Maximize(minimize) == (2.f * Nz::Vector2f::Unit())); + } + + } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Vector2f zero = Nz::Vector2f::Zero(); + Nz::Vector2f unit = Nz::Vector2f::Unit(); + REQUIRE(Nz::Vector2f::Lerp(zero, unit, 0.5f) == (Nz::Vector2f::Unit() * 0.5f)); + } + } + } } diff --git a/tests/Engine/Math/Vector3.cpp b/tests/Engine/Math/Vector3.cpp index a61016e82..84c6a01ae 100644 --- a/tests/Engine/Math/Vector3.cpp +++ b/tests/Engine/Math/Vector3.cpp @@ -26,7 +26,8 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") { REQUIRE(firstUnit.AbsDotProduct(tmp) == Approx(2.f)); REQUIRE(firstUnit.DotProduct(tmp) == Approx(0.f)); - REQUIRE(firstUnit.AngleBetween(tmp) == Approx(90.f)); + REQUIRE(firstUnit.AngleBetween(tmp) == Approx(Nz::FromDegrees(90.f))); + REQUIRE(firstUnit.AngleBetween(-firstUnit) == Approx(Nz::FromDegrees(180.f))); } } @@ -52,5 +53,48 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") REQUIRE(firstUnit.GetLength() == Approx(std::sqrt(3.f))); } } + + WHEN("We nomalize the vectors") + { + float ratio = 0.f; + THEN("For normal cases should be normal") + { + Nz::Vector3f normalized = firstUnit.GetNormal(&ratio); + REQUIRE(normalized == (Nz::Vector3f::Unit() / std::sqrt(3.f))); + REQUIRE(ratio == Approx(std::sqrt(3.f))); + } + + THEN("For null vector") + { + Nz::Vector3f zero = Nz::Vector3f::Zero(); + REQUIRE(zero.GetNormal(&ratio) == Nz::Vector3f::Zero()); + REQUIRE(ratio == Approx(0.f)); + } + } + + WHEN("We try to maximize and minimize") + { + Nz::Vector3f maximize(2.f, 1.f, 2.f); + Nz::Vector3f minimize(1.f, 2.f, 1.f); + + THEN("The minimised and maximised should be (1, 1, 1) and (2, 2, 2)") + { + Nz::Vector3f maximized = maximize; + Nz::Vector3f minimized = minimize; + REQUIRE(minimized.Minimize(maximized) == Nz::Vector3f::Unit()); + REQUIRE(maximize.Maximize(minimize) == (2.f * Nz::Vector3f::Unit())); + } + + } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Vector3f zero = Nz::Vector3f::Zero(); + Nz::Vector3f unit = Nz::Vector3f::Unit(); + REQUIRE(Nz::Vector3f::Lerp(zero, unit, 0.5f) == (Nz::Vector3f::Unit() * 0.5f)); + } + } } } diff --git a/tests/Engine/Math/Vector4.cpp b/tests/Engine/Math/Vector4.cpp index cfe91eab7..85c321ac1 100644 --- a/tests/Engine/Math/Vector4.cpp +++ b/tests/Engine/Math/Vector4.cpp @@ -39,5 +39,15 @@ SCENARIO("Vector4", "[MATH][VECTOR4]") REQUIRE(tmp.Normalize() == Nz::Vector4f(Nz::Vector3f::Unit() * (1.f / 3.f), 1.f)); } } + + WHEN("We try to lerp") + { + THEN("Compilation should be fine") + { + Nz::Vector4f zero = Nz::Vector4f::Zero(); + Nz::Vector4f unitX = Nz::Vector4f::UnitX(); + REQUIRE(Nz::Vector4f::Lerp(zero, unitX, 0.5f) == Nz::Vector4f(Nz::Vector3f::UnitX() * 0.5f, 1.f)); + } + } } } From 3247435e08efe2b4b2dda216120f84fb0aab6777 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 30 Dec 2015 15:59:08 +0100 Subject: [PATCH 043/229] Fix for Linux Former-commit-id: 8cddb6d53f658144f8659adbd7ecab67eb5a41a2 --- examples/DopplerEffect/main.cpp | 5 +++-- src/Nazara/Core/Posix/DirectoryImpl.cpp | 5 ++--- src/Nazara/Utility/X11/Display.cpp | 2 +- src/Nazara/Utility/X11/Display.hpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/DopplerEffect/main.cpp b/examples/DopplerEffect/main.cpp index 42d838356..b6d2d034b 100644 --- a/examples/DopplerEffect/main.cpp +++ b/examples/DopplerEffect/main.cpp @@ -13,12 +13,13 @@ #include // Thread::Sleep #include #include +#include #include int main() { - // NzKeyboard ne nécessite pas l'initialisation du module Utilitaire - Nz::Initializer audio; + // NzKeyboard nécessite l'initialisation du module Utilitaire + Nz::Initializer audio; if (!audio) { std::cout << "Failed to initialize audio module" << std::endl; diff --git a/src/Nazara/Core/Posix/DirectoryImpl.cpp b/src/Nazara/Core/Posix/DirectoryImpl.cpp index 4abf575b3..e3add7fd5 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.cpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.cpp @@ -70,9 +70,8 @@ namespace Nz bool DirectoryImpl::Create(const String& dirPath) { - mode_t permissions; // TODO: check permissions - - return mkdir(dirPath.GetConstBuffer(), permissions) != -1;; + mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; // TODO: check permissions, no right to execute but read and write for every others. + return mkdir(dirPath.GetConstBuffer(), permissions) != -1; } bool DirectoryImpl::Exists(const String& dirPath) diff --git a/src/Nazara/Utility/X11/Display.cpp b/src/Nazara/Utility/X11/Display.cpp index d61543dfd..2ec41ff0d 100644 --- a/src/Nazara/Utility/X11/Display.cpp +++ b/src/Nazara/Utility/X11/Display.cpp @@ -136,7 +136,7 @@ namespace Nz OpenEWMHConnection(sharedConnection); } - NazaraNotice("Initialized: Utility module"); + NazaraNotice("Initialized: Display module"); return true; } diff --git a/src/Nazara/Utility/X11/Display.hpp b/src/Nazara/Utility/X11/Display.hpp index 95177e2d2..88f80f2ee 100644 --- a/src/Nazara/Utility/X11/Display.hpp +++ b/src/Nazara/Utility/X11/Display.hpp @@ -17,7 +17,7 @@ namespace Nz { class String; - class X11 + class NAZARA_UTILITY_API X11 { public: X11() = delete; From 856df11d5c5c75c073d482b6b2fe0020ddabf0f5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Jan 2016 16:34:49 +0100 Subject: [PATCH 044/229] Math/Algorithm: Fix compilation (C++14 constexpr is not supported by all major compilers) Former-commit-id: 83c2d98885763160cedcf03cfb08aa44571703f4 --- include/Nazara/Math/Algorithm.hpp | 26 ++++++++--------- include/Nazara/Math/Algorithm.inl | 46 ++++++++++++++++++------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index c7d4dd024..74cc45593 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -30,30 +30,30 @@ namespace Nz { - template constexpr T Approach(T value, T objective, T increment); + template /*constexpr*/ T Approach(T value, T objective, T increment); template constexpr T Clamp(T value, T min, T max); - template constexpr T CountBits(T value); + template /*constexpr*/ T CountBits(T value); template constexpr T FromDegrees(T degrees); template constexpr T FromRadians(T radians); template constexpr T DegreeToRadian(T degrees); - template constexpr T GetNearestPowerOfTwo(T number); - constexpr unsigned int GetNumberLength(signed char number); - constexpr unsigned int GetNumberLength(unsigned char number); + template /*constexpr*/ T GetNearestPowerOfTwo(T number); + /*constexpr*/ unsigned int GetNumberLength(signed char number); + /*constexpr*/ unsigned int GetNumberLength(unsigned char number); unsigned int GetNumberLength(int number); - constexpr unsigned int GetNumberLength(unsigned int number); + /*constexpr*/ unsigned int GetNumberLength(unsigned int number); unsigned int GetNumberLength(long long number); - constexpr unsigned int GetNumberLength(unsigned long long number); + /*constexpr*/ unsigned int GetNumberLength(unsigned long long number); unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); - template constexpr unsigned int IntegralLog2(T number); - template constexpr unsigned int IntegralLog2Pot(T pot); - constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent); + template /*constexpr*/ unsigned int IntegralLog2(T number); + template /*constexpr*/ unsigned int IntegralLog2Pot(T pot); + /*constexpr*/ unsigned int IntegralPow(unsigned int base, unsigned int exponent); template constexpr T Lerp(const T& from, const T& to, const T2& interpolation); template constexpr T MultiplyAdd(T x, T y, T z); - template constexpr T NormalizeAngle(T angle); - template constexpr bool NumberEquals(T a, T b); - template constexpr bool NumberEquals(T a, T b, T maxDifference); + template /*constexpr*/ T NormalizeAngle(T angle); + template /*constexpr*/ bool NumberEquals(T a, T b); + template /*constexpr*/ bool NumberEquals(T a, T b, T maxDifference); String NumberToString(long long number, UInt8 radix = 10); template constexpr T RadianToDegree(T radians); long long StringToNumber(String str, UInt8 radix = 10, bool* ok = nullptr); diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index c42a1b8b5..f18ee119e 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -108,7 +108,8 @@ namespace Nz */ template - constexpr T Approach(T value, T objective, T increment) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline T Approach(T value, T objective, T increment) { if (value < objective) return std::min(value + increment, objective); @@ -141,7 +142,8 @@ namespace Nz */ template - constexpr T CountBits(T value) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline T CountBits(T value) { // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan unsigned int count = 0; @@ -209,7 +211,8 @@ namespace Nz */ template - constexpr T GetNearestPowerOfTwo(T number) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline T GetNearestPowerOfTwo(T number) { T x = 1; while (x < number) @@ -225,7 +228,8 @@ namespace Nz * \param number Number to get number of digits */ - constexpr unsigned int GetNumberLength(signed char number) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int GetNumberLength(signed char number) { // Char is expected to be 1 byte static_assert(sizeof(number) == 1, "Signed char must be one byte-sized"); @@ -251,7 +255,8 @@ namespace Nz * \param number Number to get number of digits */ - constexpr unsigned int GetNumberLength(unsigned char number) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int GetNumberLength(unsigned char number) { // Char is expected to be 1 byte static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized"); @@ -286,7 +291,8 @@ namespace Nz * \param number Number to get number of digits */ - constexpr unsigned int GetNumberLength(unsigned int number) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int GetNumberLength(unsigned int number) { if (number == 0) return 1; @@ -316,7 +322,8 @@ namespace Nz * \param number Number to get number of digits */ - constexpr unsigned int GetNumberLength(unsigned long long number) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int GetNumberLength(unsigned long long number) { if (number == 0) return 1; @@ -376,7 +383,8 @@ namespace Nz */ template - constexpr unsigned int IntegralLog2(T number) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int IntegralLog2(T number) { // Proxy needed to avoid an overload problem return Detail::IntegralLog2(number); @@ -393,7 +401,8 @@ namespace Nz */ template - constexpr unsigned int IntegralLog2Pot(T pot) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int IntegralLog2Pot(T pot) { return Detail::IntegralLog2Pot(pot); } @@ -406,7 +415,8 @@ namespace Nz * \parma exponent Power for the base */ - constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline unsigned int IntegralPow(unsigned int base, unsigned int exponent) { unsigned int r = 1; for (unsigned int i = 0; i < exponent; ++i) @@ -432,11 +442,6 @@ namespace Nz template constexpr T Lerp(const T& from, const T& to, const T2& interpolation) { - #ifdef NAZARA_DEBUG - if (interpolation < T2(0.0) || interpolation > T2(1.0)) - NazaraWarning("Interpolation should be in range [0..1] (Got " + String::Number(interpolation) + ')'); - #endif - return from + interpolation * (to - from); } @@ -448,7 +453,7 @@ namespace Nz * \param y is Y * \param z is Z * - * \remark This function is meant to use a special instruction in CPU + * \remark This function is meant to use a special faster instruction in CPU if possible */ template @@ -489,7 +494,8 @@ namespace Nz */ template - constexpr T NormalizeAngle(T angle) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline T NormalizeAngle(T angle) { #if NAZARA_MATH_ANGLE_RADIAN const T limit = T(M_PI); @@ -514,7 +520,8 @@ namespace Nz */ template - constexpr bool NumberEquals(T a, T b) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline bool NumberEquals(T a, T b) { return NumberEquals(a, b, std::numeric_limits::epsilon()); } @@ -529,7 +536,8 @@ namespace Nz */ template - constexpr bool NumberEquals(T a, T b, T maxDifference) + //TODO: Mark as constexpr when supported by all major compilers + /*constexpr*/ inline bool NumberEquals(T a, T b, T maxDifference) { if (b > a) std::swap(a, b); From 235fbf187727aef6bfa3193db8beb1464531752a Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Jan 2016 13:50:52 +0100 Subject: [PATCH 045/229] Utility/SimpleTextDrawer: Add optimized AppendText method Former-commit-id: 4608e95d19fe5256d205a0d02b75b1f496f629cc --- include/Nazara/Utility/SimpleTextDrawer.hpp | 6 + src/Nazara/Utility/SimpleTextDrawer.cpp | 244 ++++++++++---------- 2 files changed, 124 insertions(+), 126 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 68fdc1daa..d2bbd336c 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -24,6 +24,8 @@ namespace Nz SimpleTextDrawer(SimpleTextDrawer&& drawer); virtual ~SimpleTextDrawer(); + void AppendText(const String& str); + const Rectui& GetBounds() const override; unsigned int GetCharacterSize() const; const Color& GetColor() const; @@ -50,6 +52,7 @@ namespace Nz private: void ConnectFontSlots(); void DisconnectFontSlots(); + void GenerateGlyphs(const String& text) const; void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer); void OnFontInvalidated(const Font* font); void OnFontRelease(const Font* object); @@ -63,9 +66,12 @@ namespace Nz mutable std::vector m_glyphs; Color m_color; FontRef m_font; + mutable Rectf m_workingBounds; mutable Rectui m_bounds; String m_text; + mutable UInt32 m_previousCharacter; UInt32 m_style; + mutable Vector2ui m_drawPos; mutable bool m_glyphUpdated; unsigned int m_characterSize; }; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 6f7393dd9..62914cd06 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -31,9 +31,15 @@ namespace Nz operator=(std::move(drawer)); } - SimpleTextDrawer::~SimpleTextDrawer() = default; + void SimpleTextDrawer::AppendText(const String& str) + { + m_text.Append(str); + if (m_glyphUpdated) + GenerateGlyphs(str); + } + const Rectui& SimpleTextDrawer::GetBounds() const { if (!m_glyphUpdated) @@ -59,13 +65,7 @@ namespace Nz Font* SimpleTextDrawer::GetFont(unsigned int index) const { - #if NAZARA_UTILITY_SAFE - if (index > 0) - { - NazaraError("Font index out of range (" + String::Number(index) + " >= 1)"); - return nullptr; - } - #endif + NazaraAssert(index == 0, "Font index out of range"); return m_font; } @@ -215,6 +215,109 @@ namespace Nz m_glyphCacheClearedSlot.Disconnect(); } + void SimpleTextDrawer::GenerateGlyphs(const String& text) const + { + if (text.IsEmpty()) + return; + + ///TODO: Allow iteration on Unicode characters without allocating any buffer + std::u32string characters = text.GetUtf32String(); + if (characters.empty()) + { + NazaraError("Invalid character set"); + return; + } + + const Font::SizeInfo& sizeInfo = m_font->GetSizeInfo(m_characterSize); + + m_glyphs.reserve(m_glyphs.size() + characters.size()); + for (char32_t character : characters) + { + if (m_previousCharacter != 0) + m_drawPos.x += m_font->GetKerning(m_characterSize, m_previousCharacter, character); + + m_previousCharacter = character; + + bool whitespace = true; + switch (character) + { + case ' ': + m_drawPos.x += sizeInfo.spaceAdvance; + break; + + case '\n': + m_drawPos.x = 0; + m_drawPos.y += sizeInfo.lineHeight; + break; + + case '\t': + m_drawPos.x += sizeInfo.spaceAdvance * 4; + break; + + default: + whitespace = false; + break; + } + + if (whitespace) + continue; // White spaces are blanks and invisible, move the draw position and skip the rest + + const Font::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, character); + if (!fontGlyph.valid) + continue; // Glyph failed to load, just skip it (can't do much) + + Glyph glyph; + glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); + glyph.atlasRect = fontGlyph.atlasRect; + glyph.color = m_color; + glyph.flipped = fontGlyph.flipped; + + int advance = fontGlyph.advance; + + Rectf bounds(fontGlyph.aabb); + bounds.x += m_drawPos.x; + bounds.y += m_drawPos.y; + + if (fontGlyph.requireFauxBold) + { + // Let's simulate bold by enlarging the glyph (not a neat idea, but should work) + Vector2f center = bounds.GetCenter(); + + // Enlarge by 10% + bounds.width *= 1.1f; + bounds.height *= 1.1f; + + // Replace it at the correct height + Vector2f offset(bounds.GetCenter() - center); + bounds.y -= offset.y; + + // Adjust advance (+10%) + advance += advance / 10; + } + + // We "lean" the glyph to simulate italics style + float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; + float italicTop = italic * bounds.y; + float italicBottom = italic * bounds.GetMaximum().y; + + glyph.corners[0].Set(bounds.x - italicTop, bounds.y); + glyph.corners[1].Set(bounds.x + bounds.width - italicTop, bounds.y); + glyph.corners[2].Set(bounds.x - italicBottom, bounds.y + bounds.height); + glyph.corners[3].Set(bounds.x + bounds.width - italicBottom, bounds.y + bounds.height); + + if (!m_workingBounds.IsValid()) + m_workingBounds.Set(glyph.corners[0]); + + for (unsigned int i = 0; i < 4; ++i) + m_workingBounds.ExtendTo(glyph.corners[i]); + + m_drawPos.x += advance; + m_glyphs.push_back(glyph); + } + + m_bounds.Set(Rectf(std::floor(m_workingBounds.x), std::floor(m_workingBounds.y), std::ceil(m_workingBounds.width), std::ceil(m_workingBounds.height))); + } + void SimpleTextDrawer::OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer) { NazaraUnused(font); @@ -228,7 +331,7 @@ namespace Nz #endif // Update atlas layer pointer - // Note: This can happend while updating + // Note: This can happen while updating for (Glyph& glyph : m_glyphs) { if (glyph.atlas == oldLayer) @@ -269,126 +372,15 @@ namespace Nz void SimpleTextDrawer::UpdateGlyphs() const { + NazaraAssert(m_font && m_font->IsValid(), "Invalid font"); + m_bounds.MakeZero(); + m_drawPos.Set(0, m_characterSize); //< Our draw "cursor" m_glyphs.clear(); m_glyphUpdated = true; + m_previousCharacter = 0; + m_workingBounds.MakeZero(); //< Compute bounds as float to speedup bounds computation (as casting between floats and integers is costly) - #if NAZARA_UTILITY_SAFE - if (!m_font || !m_font->IsValid()) - { - NazaraError("Invalid font"); - return; - } - #endif - - if (m_text.IsEmpty()) - return; - - ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?) - std::u32string characters = m_text.GetUtf32String(); - if (characters.empty()) - { - NazaraError("Invalid character set"); - return; - } - - const Font::SizeInfo& sizeInfo = m_font->GetSizeInfo(m_characterSize); - - // "Curseur" de dessin - Vector2ui drawPos(0, m_characterSize); - - // On calcule les bornes en flottants pour accélérer les calculs (il est coûteux de changer de type trop souvent) - bool firstGlyph = true; - Rectf textBounds = Rectf::Zero(); - UInt32 previousCharacter = 0; - - m_glyphs.reserve(characters.size()); - for (char32_t character : characters) - { - if (previousCharacter != 0) - drawPos.x += m_font->GetKerning(m_characterSize, previousCharacter, character); - - previousCharacter = character; - - bool whitespace = true; - switch (character) - { - case ' ': - drawPos.x += sizeInfo.spaceAdvance; - break; - - case '\n': - drawPos.x = 0; - drawPos.y += sizeInfo.lineHeight; - break; - - case '\t': - drawPos.x += sizeInfo.spaceAdvance*4; - break; - - default: - whitespace = false; - break; - } - - if (whitespace) - continue; // Inutile d'avoir un glyphe pour un espace blanc - - const Font::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, character); - if (!fontGlyph.valid) - continue; // Le glyphe n'a pas été correctement chargé, que pouvons-nous faire d'autre que le passer - - Glyph glyph; - glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); - glyph.atlasRect = fontGlyph.atlasRect; - glyph.color = m_color; - glyph.flipped = fontGlyph.flipped; - - int advance = fontGlyph.advance; - - Rectf bounds(fontGlyph.aabb); - bounds.x += drawPos.x; - bounds.y += drawPos.y; - - if (fontGlyph.requireFauxBold) - { - // On va agrandir le glyphe pour simuler le gras (idée moisie, mais idée quand même) - Vector2f center = bounds.GetCenter(); - - bounds.width *= 1.1f; - bounds.height *= 1.1f; - - // On le replace à la bonne hauteur - Vector2f offset(bounds.GetCenter() - center); - bounds.y -= offset.y; - - // On ajuste l'espacement - advance += advance/10; - } - - // On "penche" le glyphe pour obtenir un semblant d'italique - float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; - float italicTop = italic * bounds.y; - float italicBottom = italic * bounds.GetMaximum().y; - - glyph.corners[0].Set(bounds.x - italicTop, bounds.y); - glyph.corners[1].Set(bounds.x + bounds.width - italicTop, bounds.y); - glyph.corners[2].Set(bounds.x - italicBottom, bounds.y + bounds.height); - glyph.corners[3].Set(bounds.x + bounds.width - italicBottom, bounds.y + bounds.height); - - if (firstGlyph) - { - textBounds.Set(glyph.corners[0]); - firstGlyph = false; - } - - for (unsigned int i = 0; i < 4; ++i) - textBounds.ExtendTo(glyph.corners[i]); - - drawPos.x += advance; - m_glyphs.push_back(glyph); - } - - m_bounds.Set(Rectf(std::floor(textBounds.x), std::floor(textBounds.y), std::ceil(textBounds.width), std::ceil(textBounds.height))); + GenerateGlyphs(m_text); } } From c6f491ca2157c17c17b6a9eea3b72ee92b2371c8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 6 Jan 2016 12:01:35 +0100 Subject: [PATCH 046/229] Graphics/TextSprite: Optimize Update method Make it keep established connections instead of clearing everything and connecting again Former-commit-id: abe315a03ba19059a9a867c23780c2f8cd34345b --- include/Nazara/Graphics/TextSprite.hpp | 1 + src/Nazara/Graphics/TextSprite.cpp | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 2a664a5c3..98474bd91 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -65,6 +65,7 @@ namespace Nz struct AtlasSlots { + bool used; NazaraSlot(AbstractAtlas, OnAtlasCleared, clearSlot); NazaraSlot(AbstractAtlas, OnAtlasLayerChange, layerChangeSlot); NazaraSlot(AbstractAtlas, OnAtlasRelease, releaseSlot); diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 13e4b3e49..4c380dfee 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -33,13 +33,16 @@ namespace Nz void TextSprite::Update(const AbstractTextDrawer& drawer) { - m_atlases.clear(); - CallOnExit clearOnFail([this]() { Clear(); }); + // Mark every atlas as unused... + for (auto& pair : m_atlases) + pair.second.used = false; + + // ... until they are marked as used by the drawer unsigned int fontCount = drawer.GetFontCount(); for (unsigned int i = 0; i < fontCount; ++i) { @@ -47,14 +50,28 @@ namespace Nz const AbstractAtlas* atlas = font->GetAtlas().get(); NazaraAssert(atlas->GetStorage() & DataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites"); - if (m_atlases.find(atlas) == m_atlases.end()) + auto it = m_atlases.find(atlas); + if (it == m_atlases.end()) { - AtlasSlots& atlasSlots = m_atlases[atlas]; + it = m_atlases.insert(std::make_pair(atlas, AtlasSlots())).first; + AtlasSlots& atlasSlots = it->second; atlasSlots.clearSlot.Connect(atlas->OnAtlasCleared, this, &TextSprite::OnAtlasInvalidated); atlasSlots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &TextSprite::OnAtlasLayerChange); atlasSlots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &TextSprite::OnAtlasInvalidated); } + + it->second.used = true; + } + + // Remove unused atlas slots + auto it = m_atlases.begin(); + while (it != m_atlases.end()) + { + if (!it->second.used) + m_atlases.erase(it++); + else + ++it; } unsigned int glyphCount = drawer.GetGlyphCount(); From 2b908d0c2bffc1580ae7b0ba922b040d2f03a2d2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 6 Jan 2016 13:16:11 +0100 Subject: [PATCH 047/229] Graphics/TextSprite: Fix unused memory not being released by Update Former-commit-id: 2a1349b1346d6dd11a004654a65d43e91626b76a --- src/Nazara/Graphics/TextSprite.cpp | 57 +++++++++++++++++++----------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 4c380dfee..6d0e41f52 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -65,18 +65,23 @@ namespace Nz } // Remove unused atlas slots - auto it = m_atlases.begin(); - while (it != m_atlases.end()) + auto atlasIt = m_atlases.begin(); + while (atlasIt != m_atlases.end()) { - if (!it->second.used) - m_atlases.erase(it++); + if (!atlasIt->second.used) + m_atlases.erase(atlasIt++); else - ++it; + ++atlasIt; } unsigned int glyphCount = drawer.GetGlyphCount(); m_localVertices.resize(glyphCount * 4); + // Reset glyph count for every texture to zero + for (auto& pair : m_renderInfos) + pair.second.count = 0; + + // Count glyph count for each texture Texture* lastTexture = nullptr; unsigned int* count = nullptr; for (unsigned int i = 0; i < glyphCount; ++i) @@ -86,25 +91,36 @@ namespace Nz Texture* texture = static_cast(glyph.atlas); if (lastTexture != texture) { - auto pair = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U})); + auto it = m_renderInfos.find(texture); + if (it == m_renderInfos.end()) + it = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U})).first; - count = &pair.first->second.count; + count = &it->second.count; lastTexture = texture; } (*count)++; } - // Attribution des indices + // Attributes indices and reinitialize glyph count to zero to use it as a counter in the next loop + // This is because the 1st glyph can use texture A, the 2nd glyph can use texture B and the 3th glyph C can use texture A again + // so we need a counter to know where to write informations + // also remove unused render infos unsigned int index = 0; - for (auto& pair : m_renderInfos) + auto infoIt = m_renderInfos.begin(); + while (infoIt != m_renderInfos.end()) { - RenderIndices& indices = pair.second; + RenderIndices& indices = infoIt->second; + if (indices.count == 0) + m_renderInfos.erase(infoIt++); //< No glyph uses this texture, remove from indices + else + { + indices.first = index; - indices.first = index; - - index += indices.count; - indices.count = 0; // On réinitialise count à zéro (on va s'en servir comme compteur dans la boucle suivante) + index += indices.count; + indices.count = 0; + ++infoIt; + } } lastTexture = nullptr; @@ -116,11 +132,11 @@ namespace Nz Texture* texture = static_cast(glyph.atlas); if (lastTexture != texture) { - indices = &m_renderInfos[texture]; // On a changé de texture, on ajuste le pointeur + indices = &m_renderInfos[texture]; //< We changed texture, adjust the pointer lastTexture = texture; } - // On commence par transformer les coordonnées entières en flottantes: + // First, compute the uv coordinates from our atlas rect Vector2ui size(texture->GetSize()); float invWidth = 1.f/size.x; float invHeight = 1.f/size.y; @@ -131,10 +147,11 @@ namespace Nz uvRect.width *= invWidth; uvRect.height *= invHeight; - static RectCorner normalCorners[4] = {RectCorner_LeftTop, RectCorner_RightTop, RectCorner_LeftBottom, RectCorner_RightBottom}; - static RectCorner flippedCorners[4] = {RectCorner_LeftBottom, RectCorner_LeftTop, RectCorner_RightBottom, RectCorner_RightTop}; + // Our glyph may be flipped in the atlas, to render it correctly we need to change the uv coordinates accordingly + const RectCorner normalCorners[4] = {RectCorner_LeftTop, RectCorner_RightTop, RectCorner_LeftBottom, RectCorner_RightBottom}; + const RectCorner flippedCorners[4] = {RectCorner_LeftBottom, RectCorner_LeftTop, RectCorner_RightBottom, RectCorner_RightTop}; - // Affectation des positions, couleurs, coordonnées de textures + // Set the position, color and UV of our vertices for (unsigned int j = 0; j < 4; ++j) { // Remember that indices->count is a counter here, not a count value @@ -143,7 +160,7 @@ namespace Nz m_localVertices[indices->count*4 + j].uv.Set(uvRect.GetCorner((glyph.flipped) ? flippedCorners[j] : normalCorners[j])); } - // Et on passe au prochain sommet + // Increment the counter, go to next glyph indices->count++; } From f273c0229cf85931c6c2f42fc1fe172a28c1ef98 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 6 Jan 2016 13:55:44 +0100 Subject: [PATCH 048/229] Core/String: Fix Clear(true) Former-commit-id: 8c3a60660de5fb435de83f6f5b164c6ee9f7c00b --- src/Nazara/Core/String.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 4aab9a368..76aa7510e 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -177,7 +177,6 @@ namespace Nz { EnsureOwnership(true); m_sharedString->size = 0; - m_sharedString->string.reset(); } else ReleaseString(); From b9ec4a4fc4c557768ad4b9914ae170467c269dcc Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 6 Jan 2016 19:05:26 +0100 Subject: [PATCH 049/229] Utility/SimpleTextDrawer: Add Clear method Former-commit-id: 10f7c36edb7f0d1705709b070e78792708cdbebf --- include/Nazara/Utility/SimpleTextDrawer.hpp | 3 +++ src/Nazara/Utility/SimpleTextDrawer.cpp | 27 +++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index d2bbd336c..67de92a4c 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -26,6 +26,8 @@ namespace Nz void AppendText(const String& str); + void Clear(); + const Rectui& GetBounds() const override; unsigned int GetCharacterSize() const; const Color& GetColor() const; @@ -50,6 +52,7 @@ namespace Nz static SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White); private: + void ClearGlyphs() const; void ConnectFontSlots(); void DisconnectFontSlots(); void GenerateGlyphs(const String& text) const; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 62914cd06..4efeb4332 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -11,7 +11,8 @@ namespace Nz SimpleTextDrawer::SimpleTextDrawer() : m_color(Color::White), m_style(TextStyle_Regular), - m_glyphUpdated(false) + m_glyphUpdated(false), + m_characterSize(24) { SetFont(Font::GetDefault()); } @@ -40,6 +41,12 @@ namespace Nz GenerateGlyphs(str); } + void SimpleTextDrawer::Clear() + { + m_text.Clear(true); + ClearGlyphs(); + } + const Rectui& SimpleTextDrawer::GetBounds() const { if (!m_glyphUpdated) @@ -199,6 +206,16 @@ namespace Nz return drawer; } + void SimpleTextDrawer::ClearGlyphs() const + { + m_bounds.MakeZero(); + m_drawPos.Set(0, m_characterSize); //< Our draw "cursor" + m_glyphs.clear(); + m_glyphUpdated = true; + m_previousCharacter = 0; + m_workingBounds.MakeZero(); //< Compute bounds as float to speedup bounds computation (as casting between floats and integers is costly) + } + void SimpleTextDrawer::ConnectFontSlots() { m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &SimpleTextDrawer::OnFontInvalidated); @@ -374,13 +391,7 @@ namespace Nz { NazaraAssert(m_font && m_font->IsValid(), "Invalid font"); - m_bounds.MakeZero(); - m_drawPos.Set(0, m_characterSize); //< Our draw "cursor" - m_glyphs.clear(); - m_glyphUpdated = true; - m_previousCharacter = 0; - m_workingBounds.MakeZero(); //< Compute bounds as float to speedup bounds computation (as casting between floats and integers is costly) - + ClearGlyphs(); GenerateGlyphs(m_text); } } From adf5946711dd8a6d56028d229dc3c5e100bdd879 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jan 2016 13:33:26 +0100 Subject: [PATCH 050/229] Core/Console: Add CountOf function Former-commit-id: 8ea1456bc8debae102ca616176febb15d3759d17 --- include/Nazara/Core/Algorithm.hpp | 2 ++ include/Nazara/Core/Algorithm.inl | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 408eb79cf..048c5d902 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -23,6 +23,8 @@ namespace Nz template auto Apply(O& object, F&& fn, Tuple&& t); template ByteArray ComputeHash(HashType hash, const T& v); template ByteArray ComputeHash(AbstractHash* hash, const T& v); + template constexpr std::size_t CountOf(T(&name)[N]) noexcept; + template std::size_t CountOf(const T& c); template void HashCombine(std::size_t& seed, const T& v); template diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index a23fea4e1..5977c6d42 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -62,6 +62,18 @@ namespace Nz return hash->End(); } + template + constexpr std::size_t CountOf(T(&name)[N]) noexcept + { + return N; + } + + template + std::size_t CountOf(const T& c) + { + return c.size(); + } + // Algorithme venant de CityHash par Google // http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co template From 55cfd66c7abcb8366e725b46b544f6ac8e87e28e Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jan 2016 13:43:53 +0100 Subject: [PATCH 051/229] Sdk: Add Console Former-commit-id: c80d3c9dbbb0391fdb48a2710f5b5bf7468c050d --- SDK/include/NDK/Console.hpp | 89 +++++++++++++++ SDK/include/NDK/Console.inl | 44 ++++++++ SDK/src/NDK/Console.cpp | 219 ++++++++++++++++++++++++++++++++++++ 3 files changed, 352 insertions(+) create mode 100644 SDK/include/NDK/Console.hpp create mode 100644 SDK/include/NDK/Console.inl create mode 100644 SDK/src/NDK/Console.cpp diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp new file mode 100644 index 000000000..b594c1179 --- /dev/null +++ b/SDK/include/NDK/Console.hpp @@ -0,0 +1,89 @@ +// 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_CONSOLE_HPP +#define NDK_CONSOLE_HPP + +#include +#include +#include +#include +#include + +namespace Nz +{ + class LuaInstance; +} + +namespace Ndk +{ + class Entity; + + class NDK_API Console : public Nz::Node + { + public: + Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance); + Console(const Console& console) = delete; + Console(Console&& console) = default; + ~Console() = default; + + void AddLine(const Nz::String& text, const Nz::Color& color = Nz::Color::White); + + inline const EntityHandle& GetBackground() const; + inline unsigned int GetCharacterSize() const; + inline const EntityHandle& GetHistory() const; + inline const EntityHandle& GetInput() const; + inline const Nz::Vector2f& GetSize() const; + inline const Nz::FontRef& GetTextFont() const; + + inline bool IsVisible() const; + + void SendCharacter(char32_t character); + + void SetCharacterSize(unsigned int size); + void SetSize(const Nz::Vector2f& size); + void SetTextFont(Nz::FontRef font); + + void Show(bool show = true); + + Console& operator=(const Console& console) = delete; + Console& operator=(Console&& console) = default; + + private: + void AddLineInternal(const Nz::String& text, const Nz::Color& color = Nz::Color::White); + void ExecuteInput(); + void Layout(); + void RefreshHistory(); + + struct Line + { + Nz::Color color; + Nz::String text; + }; + + std::vector m_historyLines; + EntityOwner m_background; + EntityOwner m_history; + EntityOwner m_input; + EntityOwner m_inputBackground; + Nz::FontRef m_defaultFont; + Nz::LuaInstance& m_instance; + Nz::SpriteRef m_backgroundSprite; + Nz::SpriteRef m_inputBackgroundSprite; + Nz::SimpleTextDrawer m_historyDrawer; + Nz::SimpleTextDrawer m_inputDrawer; + Nz::TextSpriteRef m_historyTextSprite; + Nz::TextSpriteRef m_inputTextSprite; + Nz::Vector2f m_size; + bool m_opened; + unsigned int m_characterSize; + unsigned int m_maxHistoryLines; + }; +} + +#include + +#endif // NDK_CONSOLE_HPP diff --git a/SDK/include/NDK/Console.inl b/SDK/include/NDK/Console.inl new file mode 100644 index 000000000..d4c3d5e2d --- /dev/null +++ b/SDK/include/NDK/Console.inl @@ -0,0 +1,44 @@ +// 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 +#include "Console.hpp" + +namespace Ndk +{ + inline const EntityHandle& Console::GetBackground() const + { + return m_background; + } + + inline unsigned int Console::GetCharacterSize() const + { + return m_characterSize; + } + + inline const EntityHandle& Console::GetHistory() const + { + return m_history; + } + + inline const EntityHandle& Console::GetInput() const + { + return m_input; + } + + inline const Nz::Vector2f& Console::GetSize() const + { + return m_size; + } + + inline const Nz::FontRef& Console::GetTextFont() const + { + return m_defaultFont; + } + + inline bool Console::IsVisible() const + { + return m_opened; + } +} diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp new file mode 100644 index 000000000..da16e3aa2 --- /dev/null +++ b/SDK/src/NDK/Console.cpp @@ -0,0 +1,219 @@ +// 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 +#include +#include +#include +#include +#include + +///TODO: For now is unable to display different color in the history, it needs a RichTextDrawer to do so + +namespace Ndk +{ + namespace + { + const char s_inputPrefix[] = "> "; + constexpr std::size_t s_inputPrefixSize = Nz::CountOf(s_inputPrefix) - 1; + } + + Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) : + m_defaultFont(Nz::Font::GetDefault()), + m_instance(instance), + m_size(size), + m_opened(false), + m_characterSize(24) + { + Nz::MaterialRef backgroundMaterial = Nz::Material::New(); + backgroundMaterial->Enable(Nz::RendererParameter_Blend, true); + backgroundMaterial->Enable(Nz::RendererParameter_DepthBuffer, false); + backgroundMaterial->SetDstBlend(Nz::BlendFunc_InvSrcAlpha); + backgroundMaterial->SetSrcBlend(Nz::BlendFunc_SrcAlpha); + + // History bakckground + m_historyBackgroundSprite = Nz::Sprite::New(); + m_historyBackgroundSprite->SetColor(Nz::Color(80, 80, 160, 128)); + m_historyBackgroundSprite->SetMaterial(backgroundMaterial); + + m_historyBackground = world.CreateEntity(); + m_historyBackground->Enable(m_opened); + m_historyBackground->AddComponent().Attach(m_historyBackgroundSprite, -1); + m_historyBackground->AddComponent().SetParent(this); + + // History + m_historyDrawer.SetCharacterSize(m_characterSize); + m_historyDrawer.SetColor(Nz::Color(200, 200, 200)); + m_historyDrawer.SetFont(m_defaultFont); + + m_historyTextSprite = Nz::TextSprite::New(); + + m_history = world.CreateEntity(); + m_history->Enable(m_opened); + m_history->AddComponent().Attach(m_historyTextSprite); + + Ndk::NodeComponent& historyNode = m_history->AddComponent(); + historyNode.SetParent(this); + + // Input background + m_inputBackgroundSprite = Nz::Sprite::New(); + m_inputBackgroundSprite->SetColor(Nz::Color(255, 255, 255, 200)); + m_inputBackgroundSprite->SetMaterial(backgroundMaterial); + + m_inputBackground = world.CreateEntity(); + m_inputBackground->Enable(m_opened); + m_inputBackground->AddComponent().Attach(m_inputBackgroundSprite, -1); + m_inputBackground->AddComponent().SetParent(this); + + // Input + m_inputDrawer.SetColor(Nz::Color::Black); + m_inputDrawer.SetCharacterSize(m_characterSize); + m_inputDrawer.SetFont(m_defaultFont); + m_inputDrawer.SetText(s_inputPrefix); + + m_inputTextSprite = Nz::TextSprite::New(); + m_inputTextSprite->Update(m_inputDrawer); + + m_input = world.CreateEntity(); + m_input->Enable(m_opened); + m_input->AddComponent().Attach(m_inputTextSprite); + + Ndk::NodeComponent& inputNode = m_input->AddComponent(); + inputNode.SetParent(this); + + Layout(); + } + + void Console::AddLine(const Nz::String& text, const Nz::Color& color) + { + AddLineInternal(text, color); + RefreshHistory(); + } + + void Console::SendCharacter(char32_t character) + { + switch (character) + { + case '\b': + { + Nz::String input = m_inputDrawer.GetText(); + if (input.GetLength() <= s_inputPrefixSize) // Prevent removal of the input prefix + return; // Ignore if no user character is there + + input.Resize(-1, Nz::String::HandleUtf8); + m_inputDrawer.SetText(input); + break; + } + + case '\r': + case '\n': + ExecuteInput(); + break; + + default: + { + if (Nz::Unicode::GetCategory(character) == Nz::Unicode::Category_Other_Control) + return; + + m_inputDrawer.AppendText(Nz::String::Unicode(character)); + break; + } + } + + m_inputTextSprite->Update(m_inputDrawer); + } + + void Console::SetCharacterSize(unsigned int size) + { + m_characterSize = size; + Layout(); + } + + void Console::SetSize(const Nz::Vector2f& size) + { + m_size = size; + m_historyBackgroundSprite->SetSize(m_size); + Layout(); + } + + void Console::SetTextFont(Nz::FontRef font) + { + Layout(); + } + + void Console::Show(bool show) + { + if (m_opened != show) + { + m_historyBackground->Enable(show); + m_history->Enable(show); + m_input->Enable(show); + m_inputBackground->Enable(show); + + m_opened = show; + } + } + + void Console::AddLineInternal(const Nz::String& text, const Nz::Color& color) + { + m_historyLines.emplace_back(Line{color, text}); + } + + void Console::ExecuteInput() + { + Nz::String input = m_inputDrawer.GetText().SubString(s_inputPrefixSize); + m_inputDrawer.SetText(s_inputPrefix); + + AddLineInternal(input); + + if (!m_instance.Execute(input)) + AddLineInternal(m_instance.GetLastError(), Nz::Color::Red); + + RefreshHistory(); + } + + void Console::Layout() + { + unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight; + + Ndk::NodeComponent& inputNode = m_input->GetComponent(); + inputNode.SetPosition(0.f, m_size.y - lineHeight - 5.f); + + float historyHeight = m_size.y - lineHeight - 5.f - 2.f; + m_historyBackgroundSprite->SetSize(m_size.x, historyHeight); + + m_maxHistoryLines = static_cast(std::ceil(historyHeight / lineHeight)); + + Ndk::NodeComponent& historyNode = m_history->GetComponent(); + historyNode.SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight); + + Ndk::NodeComponent& inputBackgroundNode = m_inputBackground->GetComponent(); + inputBackgroundNode.SetPosition(0.f, historyHeight + 2.f); + + m_inputBackgroundSprite->SetSize(m_size.x, m_size.y - historyHeight); + } + + void Console::RefreshHistory() + { + m_historyDrawer.Clear(); + auto it = m_historyLines.end(); + if (m_historyLines.size() > m_maxHistoryLines) + it -= m_maxHistoryLines; + else + it = m_historyLines.begin(); + + for (unsigned int i = 0; i < m_maxHistoryLines; ++i) + { + if (m_maxHistoryLines - i <= m_historyLines.size() && it != m_historyLines.end()) + { + m_historyDrawer.AppendText(it->text); + ++it; + } + + m_historyDrawer.AppendText(Nz::String('\n')); + } + + m_historyTextSprite->Update(m_historyDrawer); + } +} From 8441dcfa2a368cfa830405238f312e921697e276 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jan 2016 18:07:03 +0100 Subject: [PATCH 052/229] Ndk/Console: Fix compilation Former-commit-id: 3579cc6a392f1e74134e035192c5ecdd3e779266 --- SDK/include/NDK/Console.hpp | 7 ++++--- SDK/include/NDK/Console.inl | 15 ++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index b594c1179..1f0d36930 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -32,10 +32,11 @@ namespace Ndk void AddLine(const Nz::String& text, const Nz::Color& color = Nz::Color::White); - inline const EntityHandle& GetBackground() const; inline unsigned int GetCharacterSize() const; inline const EntityHandle& GetHistory() const; + inline const EntityHandle& GetHistoryBackground() const; inline const EntityHandle& GetInput() const; + inline const EntityHandle& GetInputBackground() const; inline const Nz::Vector2f& GetSize() const; inline const Nz::FontRef& GetTextFont() const; @@ -65,13 +66,13 @@ namespace Ndk }; std::vector m_historyLines; - EntityOwner m_background; + EntityOwner m_historyBackground; EntityOwner m_history; EntityOwner m_input; EntityOwner m_inputBackground; Nz::FontRef m_defaultFont; Nz::LuaInstance& m_instance; - Nz::SpriteRef m_backgroundSprite; + Nz::SpriteRef m_historyBackgroundSprite; Nz::SpriteRef m_inputBackgroundSprite; Nz::SimpleTextDrawer m_historyDrawer; Nz::SimpleTextDrawer m_inputDrawer; diff --git a/SDK/include/NDK/Console.inl b/SDK/include/NDK/Console.inl index d4c3d5e2d..5fb16bb1b 100644 --- a/SDK/include/NDK/Console.inl +++ b/SDK/include/NDK/Console.inl @@ -7,11 +7,6 @@ namespace Ndk { - inline const EntityHandle& Console::GetBackground() const - { - return m_background; - } - inline unsigned int Console::GetCharacterSize() const { return m_characterSize; @@ -22,11 +17,21 @@ namespace Ndk return m_history; } + inline const EntityHandle& Console::GetHistoryBackground() const + { + return m_historyBackground; + } + inline const EntityHandle& Console::GetInput() const { return m_input; } + inline const EntityHandle& Console::GetInputBackground() const + { + return m_inputBackground; + } + inline const Nz::Vector2f& Console::GetSize() const { return m_size; From ae6ba51380d7961883eda6a8d852676739c5574c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jan 2016 18:07:51 +0100 Subject: [PATCH 053/229] Utility: Remove useless file Former-commit-id: e3b885151fe47d60bc4904605859b98d7b4c4110 --- include/Nazara/Utility/Image.inl.save-failed | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 include/Nazara/Utility/Image.inl.save-failed diff --git a/include/Nazara/Utility/Image.inl.save-failed b/include/Nazara/Utility/Image.inl.save-failed deleted file mode 100644 index 5cb8ef42f..000000000 --- a/include/Nazara/Utility/Image.inl.save-failed +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include - -namespace Nz -{ - template - ImageRef Image::New(Args&&... args) - { - std::unique_ptr object(new Image(std::forward(args)...)); - object->SetPersistent(false); - - return object.release(); - } -} - -#include From bbaa3285307b678e13cdcc19a783ce6b64603cb3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jan 2016 01:28:49 +0100 Subject: [PATCH 054/229] Core/Bitset: Replace static members by static constexpr Former-commit-id: 0c2a2eb8d766f544016068cdc4be859be2b20dd5 --- include/Nazara/Core/Bitset.hpp | 7 ++++--- include/Nazara/Core/Bitset.inl | 9 --------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index ba60ae062..9c45b3689 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -89,9 +90,9 @@ namespace Nz Bitset& operator|=(const Bitset& bitset); Bitset& operator^=(const Bitset& bitset); - static Block fullBitMask; - static unsigned int bitsPerBlock; - static unsigned int npos; + static constexpr Block fullBitMask = std::numeric_limits::max(); + static constexpr unsigned int bitsPerBlock = std::numeric_limits::digits; + static constexpr unsigned int npos = std::numeric_limits::max(); private: unsigned int FindFirstFrom(unsigned int blockIndex) const; diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 54edf9f67..68104b093 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -521,15 +521,6 @@ namespace Nz return bit / bitsPerBlock; } - template - Block Bitset::fullBitMask = std::numeric_limits::max(); - - template - unsigned int Bitset::bitsPerBlock = std::numeric_limits::digits; - - template - unsigned int Bitset::npos = std::numeric_limits::max(); - template typename Bitset::Bit& Bitset::Bit::Flip() From 9fa8255de0667433ecb86190bc99fd745ae33526 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jan 2016 01:29:37 +0100 Subject: [PATCH 055/229] Sdk/Entity: Fix move constructor Former-commit-id: 92d28b142cf1572fef3a608cb63f0f72d1539bce --- SDK/src/NDK/Entity.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 4c0ebfb12..a2e69d2e1 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -16,6 +16,7 @@ namespace Ndk m_systemBits(std::move(entity.m_systemBits)), m_id(entity.m_id), m_world(entity.m_world), + m_enabled(entity.m_enabled), m_valid(entity.m_valid) { for (EntityHandle* handle : m_handles) From 4562243c5fcccf213e521165a2ff63f98e935c29 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jan 2016 14:00:54 +0100 Subject: [PATCH 056/229] Utility/SimpleTextDrawer: Update SetColor method (will no longer force full regeneration) Former-commit-id: 3f3043ea5c5d3add1358d50eb3f92e452d931dbf --- include/Nazara/Utility/SimpleTextDrawer.hpp | 2 ++ src/Nazara/Utility/SimpleTextDrawer.cpp | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 67de92a4c..3f87bf3bb 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -59,6 +59,7 @@ namespace Nz void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer); void OnFontInvalidated(const Font* font); void OnFontRelease(const Font* object); + void UpdateGlyphColor() const; void UpdateGlyphs() const; NazaraSlot(Font, OnFontAtlasChanged, m_atlasChangedSlot); @@ -75,6 +76,7 @@ namespace Nz mutable UInt32 m_previousCharacter; UInt32 m_style; mutable Vector2ui m_drawPos; + mutable bool m_colorUpdated; mutable bool m_glyphUpdated; unsigned int m_characterSize; }; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 4efeb4332..cc2130c05 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -11,7 +11,8 @@ namespace Nz SimpleTextDrawer::SimpleTextDrawer() : m_color(Color::White), m_style(TextStyle_Regular), - m_glyphUpdated(false), + m_colorUpdated(true), + m_glyphUpdated(true), m_characterSize(24) { SetFont(Font::GetDefault()); @@ -21,6 +22,7 @@ namespace Nz m_color(drawer.m_color), m_text(drawer.m_text), m_style(drawer.m_style), + m_colorUpdated(false), m_glyphUpdated(false), m_characterSize(drawer.m_characterSize) { @@ -86,6 +88,8 @@ namespace Nz { if (!m_glyphUpdated) UpdateGlyphs(); + else if (!m_colorUpdated) + UpdateGlyphColor(); return m_glyphs[index]; } @@ -119,7 +123,7 @@ namespace Nz { m_color = color; - m_glyphUpdated = false; + m_colorUpdated = false; } void SimpleTextDrawer::SetFont(Font* font) @@ -158,6 +162,7 @@ namespace Nz m_style = drawer.m_style; m_text = drawer.m_text; + m_colorUpdated = false; m_glyphUpdated = false; SetFont(drawer.m_font); @@ -169,6 +174,7 @@ namespace Nz DisconnectFontSlots(); m_bounds = std::move(drawer.m_bounds); + m_colorUpdated = std::move(drawer.m_colorUpdated); m_characterSize = std::move(drawer.m_characterSize); m_color = std::move(drawer.m_color); m_glyphs = std::move(drawer.m_glyphs); @@ -209,6 +215,7 @@ namespace Nz void SimpleTextDrawer::ClearGlyphs() const { m_bounds.MakeZero(); + m_colorUpdated = true; m_drawPos.Set(0, m_characterSize); //< Our draw "cursor" m_glyphs.clear(); m_glyphUpdated = true; @@ -387,6 +394,14 @@ namespace Nz SetFont(nullptr); } + void SimpleTextDrawer::UpdateGlyphColor() const + { + for (Glyph& glyph : m_glyphs) + glyph.color = m_color; + + m_colorUpdated = true; + } + void SimpleTextDrawer::UpdateGlyphs() const { NazaraAssert(m_font && m_font->IsValid(), "Invalid font"); From f49f77b75d4b9c2b5b6bb51b02d3083d9deb3869 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 13 Jan 2016 18:43:42 +0100 Subject: [PATCH 057/229] Sdk/CameraComponent: Add Size property for Orthogonal rendering Former-commit-id: 0cdebac880e7e97685c7a0a2980dba973ec651a3 --- .../NDK/Components/CameraComponent.hpp | 4 ++++ .../NDK/Components/CameraComponent.inl | 20 +++++++++++++++++++ SDK/src/NDK/Components/CameraComponent.cpp | 9 +++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index f96d32da4..d5951109b 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -41,6 +41,7 @@ namespace Ndk inline unsigned int GetLayer() const; inline const Nz::Matrix4f& GetProjectionMatrix() const override; inline Nz::ProjectionType GetProjectionType() const; + inline const Nz::Vector2f& GetSize() const; inline const Nz::RenderTarget* GetTarget() const override; inline const Nz::Rectf& GetTargetRegion() const; inline const Nz::Matrix4f& GetViewMatrix() const override; @@ -51,6 +52,8 @@ namespace Ndk inline void SetFOV(float fov); inline void SetLayer(unsigned int layer); inline void SetProjectionType(Nz::ProjectionType projection); + inline void SetSize(const Nz::Vector2f& size); + inline void SetSize(float width, float height); inline void SetTarget(const Nz::RenderTarget* renderTarget); inline void SetTargetRegion(const Nz::Rectf& region); inline void SetViewport(const Nz::Recti& viewport); @@ -89,6 +92,7 @@ namespace Ndk Nz::Rectf m_targetRegion; mutable Nz::Recti m_viewport; const Nz::RenderTarget* m_target; + Nz::Vector2f m_size; mutable bool m_frustumUpdated; mutable bool m_projectionMatrixUpdated; mutable bool m_viewMatrixUpdated; diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index 73e5b1cc3..7ff31d623 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -4,12 +4,14 @@ #include #include +#include "CameraComponent.hpp" namespace Ndk { inline CameraComponent::CameraComponent() : m_projectionType(Nz::ProjectionType_Perspective), m_targetRegion(0.f, 0.f, 1.f, 1.f), + m_size(0.f), m_target(nullptr), m_frustumUpdated(false), m_projectionMatrixUpdated(false), @@ -28,6 +30,7 @@ namespace Ndk AbstractViewer(camera), m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), + m_size(camera.m_size), m_target(nullptr), m_frustumUpdated(false), m_projectionMatrixUpdated(false), @@ -102,6 +105,11 @@ namespace Ndk return m_projectionType; } + inline const Nz::Vector2f & CameraComponent::GetSize() const + { + return m_size; + } + inline const Nz::RenderTarget* CameraComponent::GetTarget() const { return m_target; @@ -151,6 +159,18 @@ namespace Ndk InvalidateProjectionMatrix(); } + inline void CameraComponent::SetSize(const Nz::Vector2f& size) + { + m_size = size; + + InvalidateProjectionMatrix(); + } + + inline void CameraComponent::SetSize(float width, float height) + { + SetSize({width, height}); + } + inline void CameraComponent::SetTarget(const Nz::RenderTarget* renderTarget) { m_target = renderTarget; diff --git a/SDK/src/NDK/Components/CameraComponent.cpp b/SDK/src/NDK/Components/CameraComponent.cpp index ac369e566..1b7a3e06d 100644 --- a/SDK/src/NDK/Components/CameraComponent.cpp +++ b/SDK/src/NDK/Components/CameraComponent.cpp @@ -119,9 +119,14 @@ namespace Ndk switch (m_projectionType) { case Nz::ProjectionType_Orthogonal: - EnsureViewportUpdate(); + if (m_size.x <= 0.f || m_size.y <= 0.f) + { + EnsureViewportUpdate(); - m_projectionMatrix.MakeOrtho(0.f, static_cast(m_viewport.width), 0.f, static_cast(m_viewport.height), m_zNear, m_zFar); + m_projectionMatrix.MakeOrtho(0.f, static_cast(m_viewport.width), 0.f, static_cast(m_viewport.height), m_zNear, m_zFar); + } + else + m_projectionMatrix.MakeOrtho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar); break; case Nz::ProjectionType_Perspective: From 2cace84c901a8ee9302e181d032e67e8f2e7f269 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 15 Jan 2016 01:04:29 +0100 Subject: [PATCH 058/229] Math/Matrix4: Fix computations. Sometimes some values can be really small (and very close to zero) without being null. Former-commit-id: 932160043e4eb4094c7234f8cf4eb7c212966678 --- include/Nazara/Math/Matrix4.inl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index e2f604aed..a5b4fb631 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -326,7 +326,7 @@ namespace Nz #endif T det = GetDeterminant(); - if (!NumberEquals(det, F(0.0))) + if (det != T(0.0)) { // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix T inv[16]; @@ -484,7 +484,7 @@ namespace Nz #endif T det = GetDeterminantAffine(); - if (!NumberEquals(det, F(0.0))) + if (det != F(0.0)) { // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix T inv[16]; @@ -790,10 +790,7 @@ namespace Nz template bool Matrix4::IsAffine() const { - return NumberEquals(m14, F(0.0)) && - NumberEquals(m24, F(0.0)) && - NumberEquals(m34, F(0.0)) && - NumberEquals(m44, F(1.0)); + return m14 == F(0.0) && m24 == F(0.0) && m34 == F(0.0) && m44 == F(1.0); } /*! From c9a63bc72c04dc44b8d532ec48fc81f3bd1572a6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 15 Jan 2016 02:24:34 +0100 Subject: [PATCH 059/229] Core: Bring back MemoryStream class (It's not perfect but necessary until a better replacement comes out) Former-commit-id: e3106b98c9825e313525298a8d46ff9c40bf5027 --- include/Nazara/Core/MemoryStream.hpp | 58 ++++++++++++++++++ include/Nazara/Core/MemoryStream.inl | 15 +++++ src/Nazara/Core/MemoryStream.cpp | 90 ++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 include/Nazara/Core/MemoryStream.hpp create mode 100644 include/Nazara/Core/MemoryStream.inl create mode 100644 src/Nazara/Core/MemoryStream.cpp diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp new file mode 100644 index 000000000..7328b7707 --- /dev/null +++ b/include/Nazara/Core/MemoryStream.hpp @@ -0,0 +1,58 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MEMORYSTREAM_HPP +#define NAZARA_MEMORYSTREAM_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_CORE_API MemoryStream : public Stream + { + public: + MemoryStream(); + MemoryStream(const void* ptr, unsigned int size); + MemoryStream(const MemoryStream&) = default; + MemoryStream(MemoryStream&&) = default; + ~MemoryStream() = default; + + void Clear(); + + bool EndOfStream() const override; + + + const ByteArray& GetBuffer() const; + const UInt8* GetData() const; + UInt64 GetCursorPos() const override; + UInt64 GetSize() const override; + + bool SetCursorPos(UInt64 offset) override; + + MemoryStream& operator=(const MemoryStream&) = default; + MemoryStream& operator=(MemoryStream&&) = default; + + private: + void FlushStream() override; + std::size_t ReadBlock(void* buffer, std::size_t size) override; + std::size_t WriteBlock(const void* buffer, std::size_t size) override; + + ByteArray m_buffer; + UInt64 m_pos; + }; + + class AbstractHash; + + inline bool HashAppend(AbstractHash* hash, const String& string); + NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); + NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); +} + +#include + +#endif // NAZARA_MEMORYSTREAM_HPP diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl new file mode 100644 index 000000000..61b2f0bb4 --- /dev/null +++ b/include/Nazara/Core/MemoryStream.inl @@ -0,0 +1,15 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline bool HashAppend(AbstractHash* hash, const MemoryStream& stream) + { + return HashAppend(hash, stream.GetBuffer()); + } +} + +#include diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp new file mode 100644 index 000000000..757225609 --- /dev/null +++ b/src/Nazara/Core/MemoryStream.cpp @@ -0,0 +1,90 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + MemoryStream::MemoryStream() : + Stream(StreamOption_None, OpenMode_ReadWrite), + m_pos(0) + { + } + + MemoryStream::MemoryStream(const void* ptr, unsigned int size) : + MemoryStream() + { + m_buffer.Resize(size); + std::memcpy(m_buffer.GetBuffer(), ptr, size); + } + + void MemoryStream::Clear() + { + m_buffer.Clear(); + m_pos = 0; + } + + bool MemoryStream::EndOfStream() const + { + return m_pos >= m_buffer.size(); + } + + const ByteArray& MemoryStream::GetBuffer() const + { + return m_buffer; + } + + UInt64 MemoryStream::GetCursorPos() const + { + return m_pos; + } + + const UInt8* MemoryStream::GetData() const + { + return m_buffer.GetConstBuffer(); + } + + UInt64 MemoryStream::GetSize() const + { + return m_buffer.size(); + } + + bool MemoryStream::SetCursorPos(UInt64 offset) + { + m_pos = std::min(offset, m_buffer.size()); + + return true; + } + + void MemoryStream::FlushStream() + { + // Nothing to flush + } + + std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size) + { + std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); + + if (buffer) + std::memcpy(buffer, m_buffer.GetBuffer() + m_pos, readSize); + + m_pos += readSize; + return readSize; + } + + std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size) + { + std::size_t endPos = static_cast(m_pos + size); + if (endPos > m_buffer.size()) + m_buffer.Resize(endPos); + + std::memcpy(m_buffer.GetBuffer(), buffer, size); + + m_pos = endPos; + return size; + } +} From d2a1bc3fd5fbb1bc517ab1e8024170efe4b62838 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 15 Jan 2016 08:29:58 +0100 Subject: [PATCH 060/229] Network: Fix some move stuff Former-commit-id: 33b24a038319b444b9a3b84cfeea38c8305e6568 --- include/Nazara/Network/AbstractSocket.hpp | 3 +++ include/Nazara/Network/TcpClient.hpp | 4 +++- include/Nazara/Network/TcpClient.inl | 11 ----------- src/Nazara/Network/AbstractSocket.cpp | 16 ++++++++++++++++ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index 1eab38241..7b8327cb1 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -35,6 +35,9 @@ namespace Nz unsigned int QueryAvailableBytes() const; + AbstractSocket& operator=(const AbstractSocket&) = delete; + AbstractSocket& operator=(AbstractSocket&& abstractSocket); + // Signals: NazaraSignal(OnStateChange, const AbstractSocket* /*socket*/, SocketState /*newState*/); diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index f06a43836..cbf501ffe 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -21,7 +21,7 @@ namespace Nz public: inline TcpClient(); - inline TcpClient(TcpClient&& tcpClient); + TcpClient(TcpClient&& tcpClient) = default; ~TcpClient() = default; SocketState Connect(const IpAddress& remoteAddress); @@ -50,6 +50,8 @@ namespace Nz bool WaitForConnected(UInt64 msTimeout = 3000); + inline TcpClient& operator=(TcpClient&& tcpClient) = default; + private: void FlushStream() override; diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index 5348d2152..da292b982 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -17,17 +17,6 @@ namespace Nz { } - inline TcpClient::TcpClient(TcpClient&& tcpClient) : - AbstractSocket(std::move(tcpClient)), - Stream(std::move(tcpClient)), - m_peerAddress(std::move(tcpClient.m_peerAddress)), - m_keepAliveInterval(tcpClient.m_keepAliveInterval), - m_keepAliveTime(tcpClient.m_keepAliveTime), - m_isLowDelayEnabled(tcpClient.m_isLowDelayEnabled), - m_isKeepAliveEnabled(tcpClient.m_isKeepAliveEnabled) - { - } - inline void TcpClient::Disconnect() { Close(); diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index 1406741ff..c24ae43f9 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -107,4 +107,20 @@ namespace Nz m_handle = handle; OnOpened(); } + + AbstractSocket& AbstractSocket::operator=(AbstractSocket&& abstractSocket) + { + Close(); + + m_handle = abstractSocket.m_handle; + m_protocol = abstractSocket.m_protocol; + m_isBlockingEnabled = abstractSocket.m_isBlockingEnabled; + m_lastError = abstractSocket.m_lastError; + m_state = abstractSocket.m_state; + m_type = abstractSocket.m_type; + + abstractSocket.m_handle = SocketImpl::InvalidHandle; + + return *this; + } } From 9ae27d990cf8a44f8ff432afb8ad3c66335248a5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:11:59 +0100 Subject: [PATCH 061/229] Network/Socket: (Windows) Handle WSAECONNABORTED and WSAECONNRESET error messages Former-commit-id: 3923999541c8ba069452b1704c40bea10a6938fa --- src/Nazara/Network/Win32/SocketImpl.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 7d83ce99d..fb788f0e6 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -666,6 +666,12 @@ namespace Nz case WSAECONNREFUSED: return SocketError_ConnectionRefused; + case WSAECONNABORTED: + case WSAECONNRESET: + case WSAENOTCONN: + case WSAESHUTDOWN: + return SocketError_ConnectionClosed; + case WSAEMSGSIZE: return SocketError_DatagramSize; @@ -674,10 +680,6 @@ namespace Nz case WSA_NOT_ENOUGH_MEMORY: return SocketError_ResourceError; - case WSAENOTCONN: - case WSAESHUTDOWN: - return SocketError_ConnectionClosed; - case WSAEHOSTUNREACH: return SocketError_UnreachableHost; From c359c6925edc38c5989c0935f09c676d37ba42aa Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:14:07 +0100 Subject: [PATCH 062/229] Graphics/SpriteLibrary: Fix missing initialization/uninitialization (fixes crash at exit) Former-commit-id: c7bbd781d163a8456f1fadd0f71451adc5a1bd1a --- include/Nazara/Graphics/Sprite.hpp | 6 ++++++ src/Nazara/Graphics/Graphics.cpp | 8 ++++++++ src/Nazara/Graphics/Sprite.cpp | 16 ++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index e61f19840..3660bf872 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -23,6 +23,9 @@ namespace Nz class NAZARA_GRAPHICS_API Sprite : public InstancedRenderable { + friend SpriteLibrary; + friend class Graphics; + public: inline Sprite(); inline Sprite(MaterialRef material); @@ -57,6 +60,9 @@ namespace Nz void MakeBoundingVolume() const override; void UpdateData(InstanceData* instanceData) const override; + static bool Initialize(); + static void Uninitialize(); + Color m_color; MaterialRef m_material; Rectf m_textureCoords; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 7560573ef..a96f2f4e7 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,12 @@ namespace Nz return false; } + if (!Sprite::Initialize()) + { + NazaraError("Failed to initialize sprites"); + return false; + } + // Loaders Loaders::RegisterOBJ(); @@ -181,6 +188,7 @@ namespace Nz ParticleController::Uninitialize(); Material::Uninitialize(); SkyboxBackground::Uninitialize(); + Sprite::Uninitialize(); NazaraNotice("Uninitialized: Graphics module"); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 970254294..fd4ab758f 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -51,5 +51,21 @@ namespace Nz *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightBottom); } + bool Sprite::Initialize() + { + if (!SpriteLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + return true; + } + + void Sprite::Uninitialize() + { + SpriteLibrary::Uninitialize(); + } + SpriteLibrary::LibraryMap Sprite::s_library; } From df7d736b230608c53fd13ea8d21fc4337a320e02 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:15:17 +0100 Subject: [PATCH 063/229] Physics/Geom: Fix missing initialization/uninitialization (fixes crash at exit) Former-commit-id: 94e4ec331cd559ba4a2680f36325f25a7d2333f2 --- include/Nazara/Physics/Geom.hpp | 6 ++++++ src/Nazara/Physics/Geom.cpp | 16 ++++++++++++++++ src/Nazara/Physics/Physics.cpp | 8 ++++++++ 3 files changed, 30 insertions(+) diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 3e3d14164..34b6c58ba 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -39,6 +39,9 @@ namespace Nz class NAZARA_PHYSICS_API PhysGeom : public RefCounted { + friend PhysGeomLibrary; + friend class Physics; + public: PhysGeom() = default; PhysGeom(const PhysGeom&) = delete; @@ -64,6 +67,9 @@ namespace Nz protected: virtual NewtonCollision* CreateHandle(PhysWorld* world) const = 0; + static bool Initialize(); + static void Uninitialize(); + mutable std::unordered_map m_handles; static PhysGeomLibrary::LibraryMap s_library; diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index abe1b6e03..e814b8618 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -148,6 +148,22 @@ namespace Nz return CreateGeomFromPrimitive(list.GetPrimitive(0)); } + bool PhysGeom::Initialize() + { + if (!PhysGeomLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + return true; + } + + void PhysGeom::Uninitialize() + { + PhysGeomLibrary::Uninitialize(); + } + PhysGeomLibrary::LibraryMap PhysGeom::s_library; /********************************** BoxGeom **********************************/ diff --git a/src/Nazara/Physics/Physics.cpp b/src/Nazara/Physics/Physics.cpp index 3c53ff9ad..584c334ab 100644 --- a/src/Nazara/Physics/Physics.cpp +++ b/src/Nazara/Physics/Physics.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,11 @@ namespace Nz s_moduleReferenceCounter++; // Initialisation du module + if (!PhysGeom::Initialize()) + { + NazaraError("Failed to initialize geoms"); + return false; + } NazaraNotice("Initialized: Physics module"); return true; @@ -57,6 +63,8 @@ namespace Nz } // Libération du module + PhysGeom::Uninitialize(); + s_moduleReferenceCounter = 0; NazaraNotice("Uninitialized: Physics module"); From c94c525446f0797721acff69ad632211ac1dafd9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:15:44 +0100 Subject: [PATCH 064/229] Graphics/TextSprite: Add convenience constructor Former-commit-id: f6ca6499baf20e561616251950e7749350516b14 --- include/Nazara/Graphics/TextSprite.hpp | 1 + include/Nazara/Graphics/TextSprite.inl | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 98474bd91..db99077e2 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -28,6 +28,7 @@ namespace Nz { public: inline TextSprite(); + inline TextSprite(const AbstractTextDrawer& drawer); inline TextSprite(const TextSprite& sprite); ~TextSprite() = default; diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index cc230873d..312658557 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -14,6 +14,12 @@ namespace Nz SetDefaultMaterial(); } + inline TextSprite::TextSprite(const AbstractTextDrawer& drawer) : + TextSprite() + { + Update(drawer); + } + inline TextSprite::TextSprite(const TextSprite& sprite) : InstancedRenderable(sprite), m_renderInfos(sprite.m_renderInfos), From e907db7de152eb1fbdb63bb3e7e22fb23520a0a9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:19:27 +0100 Subject: [PATCH 065/229] Core/ObjectRef: Make hashable Former-commit-id: 42dd274e98f24c09612321e2f8d0e957463748d8 --- include/Nazara/Core/ObjectRef.inl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index 2e933bdf0..1337f0c39 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -152,4 +152,17 @@ namespace Nz } } +namespace std +{ + template + struct hash> + { + size_t operator()(const Nz::ObjectRef& object) const + { + hash h; + return h(object.Get()); + } + }; +} + #include From 2b85c9343387aff7cde541d6c7ec46478eb0b0fc Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:20:38 +0100 Subject: [PATCH 066/229] Sdk/EntityOwner: Prevent copy (Copying an EntityOwner has no use) Former-commit-id: 628eb865509a84de19bf97bf8253960d6bfb0005 --- SDK/include/NDK/EntityOwner.hpp | 5 ++--- SDK/include/NDK/EntityOwner.inl | 18 +----------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/SDK/include/NDK/EntityOwner.hpp b/SDK/include/NDK/EntityOwner.hpp index 3e2b6cdab..94dcf0566 100644 --- a/SDK/include/NDK/EntityOwner.hpp +++ b/SDK/include/NDK/EntityOwner.hpp @@ -16,16 +16,15 @@ namespace Ndk public: EntityOwner() = default; explicit EntityOwner(Entity* entity); - EntityOwner(const EntityOwner& handle); + EntityOwner(const EntityOwner& handle) = delete; EntityOwner(EntityOwner&& handle); ~EntityOwner(); void Reset(Entity* entity = nullptr); - void Reset(const EntityOwner& handle); void Reset(EntityOwner&& handle); EntityOwner& operator=(Entity* entity); - EntityOwner& operator=(const EntityOwner& handle); + EntityOwner& operator=(const EntityOwner& handle) = delete; EntityOwner& operator=(EntityOwner&& handle); }; } diff --git a/SDK/include/NDK/EntityOwner.inl b/SDK/include/NDK/EntityOwner.inl index c2335268f..e32094eaa 100644 --- a/SDK/include/NDK/EntityOwner.inl +++ b/SDK/include/NDK/EntityOwner.inl @@ -14,11 +14,6 @@ namespace Ndk Reset(entity); } - inline EntityOwner::EntityOwner(const EntityOwner& handle) : - EntityHandle(handle) - { - } - inline EntityOwner::EntityOwner(EntityOwner&& handle) : EntityHandle(std::move(handle)) { @@ -37,14 +32,10 @@ namespace Ndk EntityHandle::Reset(entity); } - inline void EntityOwner::Reset(const EntityOwner& handle) - { - Reset(handle.GetEntity()); - } - inline void EntityOwner::Reset(EntityOwner&& handle) { Reset(handle.GetEntity()); + handle.m_entity = nullptr; } inline EntityOwner& EntityOwner::operator=(Entity* entity) @@ -54,13 +45,6 @@ namespace Ndk return *this; } - inline EntityOwner& EntityOwner::operator=(const EntityOwner& handle) - { - Reset(handle); - - return *this; - } - inline EntityOwner& EntityOwner::operator=(EntityOwner&& handle) { Reset(std::move(handle)); From d6827163cdb72d30916e7cea1b8da4d08634a18d Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:21:20 +0100 Subject: [PATCH 067/229] Core/MemoryStream: Fix Writing Former-commit-id: 05a1b8a3baf79642af50ee34aea53195eff25df2 --- src/Nazara/Core/MemoryStream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 757225609..d141e2b15 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -70,7 +70,7 @@ namespace Nz std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); if (buffer) - std::memcpy(buffer, m_buffer.GetBuffer() + m_pos, readSize); + std::memcpy(buffer, &m_buffer[m_pos], readSize); m_pos += readSize; return readSize; @@ -82,7 +82,7 @@ namespace Nz if (endPos > m_buffer.size()) m_buffer.Resize(endPos); - std::memcpy(m_buffer.GetBuffer(), buffer, size); + std::memcpy(&m_buffer[m_pos], buffer, size); m_pos = endPos; return size; From ffb6a4743527fc3f93b541ea52b50fad6bfe9349 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 19 Jan 2016 12:22:43 +0100 Subject: [PATCH 068/229] Graphics/Material: Standardize flag testing Former-commit-id: f2207fa4f1ad600aa09d8b484559bd9155a11f47 --- src/Nazara/Graphics/Material.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 0781c6919..0a4755c03 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -677,7 +677,7 @@ namespace Nz flags & ShaderFlags_TextureOverlay); list.SetParameter("TRANSFORM", m_transformEnabled); - list.SetParameter("FLAG_BILLBOARD", static_cast(flags & ShaderFlags_Billboard)); + list.SetParameter("FLAG_BILLBOARD", static_cast((flags & ShaderFlags_Billboard) != 0)); list.SetParameter("FLAG_DEFERRED", static_cast((flags & ShaderFlags_Deferred) != 0)); list.SetParameter("FLAG_INSTANCING", static_cast((flags & ShaderFlags_Instancing) != 0)); list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast((flags & ShaderFlags_TextureOverlay) != 0)); From 450b80716efb333455b40eb9a99c4f79f3e68b0f Mon Sep 17 00:00:00 2001 From: GigAnon Date: Tue, 19 Jan 2016 17:54:21 +0100 Subject: [PATCH 069/229] Trying to fix premake Upgrading to premake5 fix Visual Studio 15, but breaks Code::Blocks. Former-commit-id: 75d7a3b01616b5b5e7f9cdf376ebd8386336219c --- build/Build CodeBlocks (complete, united).bat | 2 +- build/Build CodeLite (complete).bat | 2 +- build/Build CodeLite (complete, united).bat | 2 +- build/Build Visual Studio 2013 (complete).bat | 1 - ... Visual Studio 2013 (complete, united).bat | 1 - build/Build Visual Studio 2015 (complete).bat | 1 + ... Visual Studio 2015 (complete, united).bat | 1 + build/Encode Resources.bat | 2 +- build/Generate Headers.bat | 2 +- build/Parse Unicode.bat | 2 +- build/scripts/common5.lua | 839 ++++++++++++++++++ 11 files changed, 847 insertions(+), 8 deletions(-) delete mode 100644 build/Build Visual Studio 2013 (complete).bat delete mode 100644 build/Build Visual Studio 2013 (complete, united).bat create mode 100644 build/Build Visual Studio 2015 (complete).bat create mode 100644 build/Build Visual Studio 2015 (complete, united).bat create mode 100644 build/scripts/common5.lua diff --git a/build/Build CodeBlocks (complete, united).bat b/build/Build CodeBlocks (complete, united).bat index b7c5ab4c9..28aaad58f 100644 --- a/build/Build CodeBlocks (complete, united).bat +++ b/build/Build CodeBlocks (complete, united).bat @@ -1 +1 @@ -premake4 --united --with-extlibs --with-examples codeblocks \ No newline at end of file +premake5 --united --with-extlibs --with-examples codeblocks \ No newline at end of file diff --git a/build/Build CodeLite (complete).bat b/build/Build CodeLite (complete).bat index 50567ca6b..8584e6d9b 100644 --- a/build/Build CodeLite (complete).bat +++ b/build/Build CodeLite (complete).bat @@ -1 +1 @@ -premake4 --with-extlibs --with-examples codelite \ No newline at end of file +premake5 --with-extlibs --with-examples codelite \ No newline at end of file diff --git a/build/Build CodeLite (complete, united).bat b/build/Build CodeLite (complete, united).bat index d8c8c873e..52a80f504 100644 --- a/build/Build CodeLite (complete, united).bat +++ b/build/Build CodeLite (complete, united).bat @@ -1 +1 @@ -premake4 --united --with-extlibs --with-examples codelite \ No newline at end of file +premake5 --united --with-extlibs --with-examples codelite \ No newline at end of file diff --git a/build/Build Visual Studio 2013 (complete).bat b/build/Build Visual Studio 2013 (complete).bat deleted file mode 100644 index 48e93ac65..000000000 --- a/build/Build Visual Studio 2013 (complete).bat +++ /dev/null @@ -1 +0,0 @@ -premake4 --with-extlibs --with-examples vs2013 \ No newline at end of file diff --git a/build/Build Visual Studio 2013 (complete, united).bat b/build/Build Visual Studio 2013 (complete, united).bat deleted file mode 100644 index d51558a25..000000000 --- a/build/Build Visual Studio 2013 (complete, united).bat +++ /dev/null @@ -1 +0,0 @@ -premake4 --united --with-extlibs --with-examples vs2013 \ No newline at end of file diff --git a/build/Build Visual Studio 2015 (complete).bat b/build/Build Visual Studio 2015 (complete).bat new file mode 100644 index 000000000..2dd6e578a --- /dev/null +++ b/build/Build Visual Studio 2015 (complete).bat @@ -0,0 +1 @@ +premake5 --with-extlibs --with-examples vs2015 \ No newline at end of file diff --git a/build/Build Visual Studio 2015 (complete, united).bat b/build/Build Visual Studio 2015 (complete, united).bat new file mode 100644 index 000000000..aaab1938c --- /dev/null +++ b/build/Build Visual Studio 2015 (complete, united).bat @@ -0,0 +1 @@ +premake5 --united --with-extlibs --with-examples vs2015 \ No newline at end of file diff --git a/build/Encode Resources.bat b/build/Encode Resources.bat index 19afc44cf..8e4abde48 100644 --- a/build/Encode Resources.bat +++ b/build/Encode Resources.bat @@ -1,2 +1,2 @@ -premake4 encoderesources +premake5 encoderesources pause \ No newline at end of file diff --git a/build/Generate Headers.bat b/build/Generate Headers.bat index 41ac7b82a..a78069501 100644 --- a/build/Generate Headers.bat +++ b/build/Generate Headers.bat @@ -1,2 +1,2 @@ -premake4 generateheaders +premake5 generateheaders pause \ No newline at end of file diff --git a/build/Parse Unicode.bat b/build/Parse Unicode.bat index 66244ff4a..75ef2d7da 100644 --- a/build/Parse Unicode.bat +++ b/build/Parse Unicode.bat @@ -1,2 +1,2 @@ -premake4 parseunicode +premake5 parseunicode pause \ No newline at end of file diff --git a/build/scripts/common5.lua b/build/scripts/common5.lua new file mode 100644 index 000000000..b32205e27 --- /dev/null +++ b/build/scripts/common5.lua @@ -0,0 +1,839 @@ +NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table + +function NazaraBuild:Execute() + 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 + end + + if (self.Actions[_ACTION] == nil) then + local makeLibDir = os.is("windows") and "mingw" or "gmake" + + if (#self.OrderedExtLibs > 0) then + solution("NazaraExtlibs") + platforms({"x32", "x64"}) + + -- Configuration générale + configurations({ + "DebugStatic", + "ReleaseStatic" + }) + + includedirs("../extlibs/include") + libdirs("../extlibs/lib/common") + location(_ACTION) + kind("StaticLib") + + configuration("x32") + libdirs("../extlibs/lib/common/x86") + + configuration("x64") + libdirs("../extlibs/lib/common/x64") + + configuration({"codeblocks or codelite or gmake", "x32"}) + libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") + targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") + + configuration({"codeblocks or codelite or gmake", "x64"}) + libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") + targetdir("../extlibs/lib/" .. makeLibDir .. "/x64") + + configuration("vs*") + buildoptions("/MP") + + configuration({"vs*", "x32"}) + libdirs("../extlibs/lib/msvc/x86") + targetdir("../extlibs/lib/msvc/x86") + + configuration({"vs*", "x64"}) + libdirs("../extlibs/lib/msvc/x64") + targetdir("../extlibs/lib/msvc/x64") + + configuration({"xcode3 or xcode4", "x32"}) + libdirs("../extlibs/lib/xcode/x86") + targetdir("../extlibs/lib/xcode/x86") + + configuration({"xcode3 or xcode4", "x64"}) + libdirs("../extlibs/lib/xcode/x64") + targetdir("../extlibs/lib/xcode/x64") + + configuration("Debug*") + flags("Symbols") + + configuration("Release*") + flags({"EnableSSE2", "Optimize", "OptimizeSpeed", "NoFramePointer"}) + rtti("Off") + + configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) + buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants + buildoptions("-ftree-vectorize") -- Activation de la vectorisation du code + + configuration("DebugStatic") + targetsuffix("-s-d") + + configuration("ReleaseStatic") + targetsuffix("-s") + + configuration("codeblocks or codelite or gmake or xcode3 or xcode4") + buildoptions({"-fPIC", "-std=c++14"}) + + for k, libTable in ipairs(self.OrderedExtLibs) do + project(libTable.Name) + + language(libTable.Language) + location(_ACTION .. "/extlibs") + + files(libTable.Files) + excludes(libTable.FilesExclusion) + + defines(libTable.Defines) + flags(libTable.Flags) + includedirs(libTable.Includes) + links(libTable.Libraries) + + for k,v in pairs(libTable.ConfigurationLibraries) do + configuration(k) + links(v) + end + + configuration({}) + end + end + + solution("NazaraEngine") + platforms({"x32", "x64"}) + + -- Configuration générale + configurations({ + -- "DebugStatic", + -- "ReleaseStatic", + "DebugDynamic", + "ReleaseDynamic" + }) + + language("C++") + location(_ACTION) + + configuration("Debug*") + defines("NAZARA_DEBUG") + flags("Symbols") + + configuration("Release*") + flags({"EnableSSE2", "Optimize", "OptimizeSpeed", "NoFramePointer"}) + rtti("Off") + + configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) + buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants + buildoptions("-ftree-vectorize") -- Activation de la vectorisation du code + + configuration("*Static") + defines("NAZARA_STATIC") + + configuration("codeblocks or codelite or gmake or xcode3 or xcode4") + buildoptions("-std=c++14") + + configuration({"linux or bsd or macosx", "gmake"}) + buildoptions("-fvisibility=hidden") + + configuration({"linux or bsd or macosx", "gmake"}) + buildoptions("-fvisibility=hidden") + + configuration("vs*") + buildoptions("/MP") -- Multiprocessus build + flags("NoMinimalRebuild") + defines("_CRT_SECURE_NO_WARNINGS") + defines("_SCL_SECURE_NO_WARNINGS") + + + -- Spécification des modules + if (_OPTIONS["united"]) then + project("NazaraEngine") + end + + for k, moduleTable in ipairs(self.OrderedModules) do + if (not _OPTIONS["united"]) then + project("Nazara" .. moduleTable.Name) + end + + location(_ACTION .. "/modules") + + defines("NAZARA_BUILD") + + includedirs({ + "../include", + "../src/", + "../extlibs/include" + }) + + libdirs("../lib") + libdirs("../extlibs/lib/common") + + configuration("x32") + libdirs("../extlibs/lib/common/x86") + + configuration("x64") + defines("NAZARA_PLATFORM_x64") + libdirs("../extlibs/lib/common/x64") + + configuration({"codeblocks or codelite or gmake", "x32"}) + libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") + libdirs("../lib/" .. makeLibDir .. "/x86") + targetdir("../lib/" .. makeLibDir .. "/x86") + + configuration({"codeblocks or codelite or gmake", "x64"}) + libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") + libdirs("../lib/" .. makeLibDir .. "/x64") + targetdir("../lib/" .. makeLibDir .. "/x64") + + configuration({"vs*", "x32"}) + libdirs("../extlibs/lib/msvc/x86") + libdirs("../lib/msvc/x86") + targetdir("../lib/msvc/x86") + + configuration({"vs*", "x64"}) + libdirs("../extlibs/lib/msvc/x64") + libdirs("../lib/msvc/x64") + targetdir("../lib/msvc/x64") + + configuration({"xcode3 or xcode4", "x32"}) + libdirs("../extlibs/lib/xcode/x86") + libdirs("../lib/xcode/x86") + targetdir("../lib/xcode/x86") + + configuration({"xcode3 or xcode4", "x64"}) + libdirs("../extlibs/lib/xcode/x64") + libdirs("../lib/xcode/x64") + targetdir("../lib/xcode/x64") + + configuration("*Static") + kind("StaticLib") + + configuration("*Dynamic") + kind("SharedLib") + + configuration("DebugStatic") + targetsuffix("-s-d") + + configuration("ReleaseStatic") + targetsuffix("-s") + + configuration("DebugDynamic") + targetsuffix("-d") + + configuration({}) + + files(moduleTable.Files) + excludes(moduleTable.FilesExclusion) + + defines(moduleTable.Defines) + flags(moduleTable.Flags) + includedirs(moduleTable.Includes) + links(moduleTable.Libraries) + + for k,v in pairs(moduleTable.ConfigurationLibraries) do + configuration(k) + links(v) + end + + configuration({}) + end + + -- Tools + for k, toolTable in ipairs(self.OrderedTools) do + project("Nazara" .. toolTable.Name) + + location(_ACTION .. "/tools") + targetdir(toolTable.Directory) + + if (toolTable.Kind == "library") then + kind("SharedLib") + elseif (toolTable.Kind == "consoleapp") then + debugdir(toolTable.Directory) + kind("ConsoleApp") + elseif (toolTable.Kind == "windowapp") then + debugdir(toolTable.Directory) + kind("WindowedApp") + else + assert(false, "wut") + end + + includedirs({ + "../include", + "../extlibs/include" + }) + + libdirs("../lib") + libdirs("../extlibs/lib/common") + + configuration("x32") + libdirs("../extlibs/lib/common/x86") + + configuration("x64") + defines("NAZARA_PLATFORM_x64") + libdirs("../extlibs/lib/common/x64") + + configuration({"codeblocks or codelite or gmake", "x32"}) + libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") + libdirs("../lib/" .. makeLibDir .. "/x86") + if (toolTable.Kind == "library") then + targetdir("../lib/" .. makeLibDir .. "/x86") + end + + configuration({"codeblocks or codelite or gmake", "x64"}) + libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") + libdirs("../lib/" .. makeLibDir .. "/x64") + if (toolTable.Kind == "library") then + targetdir("../lib/" .. makeLibDir .. "/x64") + end + + configuration({"vs*", "x32"}) + libdirs("../extlibs/lib/msvc/x86") + libdirs("../lib/msvc/x86") + if (toolTable.Kind == "library") then + targetdir("../lib/msvc/x86") + end + + configuration({"vs*", "x64"}) + libdirs("../extlibs/lib/msvc/x64") + libdirs("../lib/msvc/x64") + if (toolTable.Kind == "library") then + targetdir("../lib/msvc/x64") + end + + configuration({"xcode3 or xcode4", "x32"}) + libdirs("../extlibs/lib/xcode/x86") + libdirs("../lib/xcode/x86") + if (toolTable.Kind == "library") then + targetdir("../lib/xcode/x86") + end + + configuration({"xcode3 or xcode4", "x64"}) + libdirs("../extlibs/lib/xcode/x64") + libdirs("../lib/xcode/x64") + if (toolTable.Kind == "library") then + targetdir("../lib/xcode/x64") + end + + if (toolTable.Kind == "library") then + configuration("*Static") + kind("StaticLib") + + configuration("*Dynamic") + kind("SharedLib") + + configuration("DebugStatic") + targetsuffix("-s-d") + + configuration("ReleaseStatic") + targetsuffix("-s") + + configuration("DebugDynamic") + targetsuffix("-d") + end + + configuration({}) + + files(toolTable.Files) + excludes(toolTable.FilesExclusion) + + defines(toolTable.Defines) + flags(toolTable.Flags) + includedirs(toolTable.Includes) + links(toolTable.Libraries) + + for k,v in pairs(toolTable.ConfigurationLibraries) do + configuration(k) + links(v) + end + + configuration({}) + end + + for k, exampleTable in ipairs(self.OrderedExamples) do + project("Demo" .. exampleTable.Name) + + location(_ACTION .. "/examples") + + if (exampleTable.Console) then + kind("ConsoleApp") + else + kind("Window") + end + + debugdir("../examples/bin") + includedirs({ + "../include", + "../extlibs/include" + }) + libdirs("../lib") + targetdir("../examples/bin") + + files(exampleTable.Files) + excludes(exampleTable.FilesExclusion) + + defines(exampleTable.Defines) + flags(exampleTable.Flags) + includedirs(exampleTable.Includes) + links(exampleTable.Libraries) + + configuration("x32") + libdirs("../extlibs/lib/common/x86") + + configuration("x64") + defines("NAZARA_PLATFORM_x64") + libdirs("../extlibs/lib/common/x64") + + configuration({"codeblocks or codelite or gmake", "x32"}) + libdirs("../lib/" .. makeLibDir .. "/x86") + + configuration({"codeblocks or codelite or gmake", "x64"}) + libdirs("../lib/" .. makeLibDir .. "/x64") + + configuration({"vs*", "x32"}) + libdirs("../lib/msvc/x86") + + configuration({"vs*", "x64"}) + libdirs("../lib/msvc/x64") + + configuration({"xcode3 or xcode4", "x32"}) + libdirs("../lib/xcode/x86") + + configuration({"xcode3 or xcode4", "x64"}) + libdirs("../lib/xcode/x64") + + for k,v in pairs(exampleTable.ConfigurationLibraries) do + configuration(k) + links(v) + end + + configuration({}) + end + end +end + +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.Examples = {} + self.ExtLibs = {} + self.Modules = {} + self.Tools = {} + + -- Actions + modules = os.matchfiles("scripts/actions/*.lua") + for k,v in pairs(modules) do + local f, err = loadfile(v) + if (f) then + ACTION = {} + + f() + + local succeed, err = self:RegisterAction(ACTION) + if (not succeed) then + print("Unable to register action: " .. err) + end + else + print("Unable to load action file: " .. err) + end + end + ACTION = nil + + -- Extern libraries + if (_OPTIONS["with-extlibs"]) then + local extlibs = os.matchfiles("../extlibs/build/*.lua") + for k,v in pairs(extlibs) do + local f, err = loadfile(v) + if (f) then + LIBRARY = {} + self:SetupInfoTable(LIBRARY) + + f() + + local succeed, err = self:RegisterExternLibrary(LIBRARY) + if (not succeed) then + print("Unable to register extern library: " .. err) + end + else + print("Unable to load extern library file: " .. err) + end + end + LIBRARY = nil + end + + -- Then the modules + local modules = os.matchfiles("scripts/modules/*.lua") + for k,v in pairs(modules) do + local moduleName = v:match(".*/(.*).lua") + 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) + if (f) then + MODULE = {} + self:SetupInfoTable(MODULE) + + f() + + local succeed, err = self:RegisterModule(MODULE) + if (not succeed) then + print("Unable to register module: " .. err) + end + else + print("Unable to load module file: " .. err) + end + end + end + MODULE = nil + + -- Continue with the tools (ex: SDK) + local tools = os.matchfiles("scripts/tools/*.lua") + for k,v in pairs(tools) do + local toolName = v:match(".*/(.*).lua") + 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) + if (f) then + TOOL = {} + self:SetupInfoTable(TOOL) + + f() + + local succeed, err = self:RegisterTool(TOOL) + if (not succeed) then + print("Unable to register tool: " .. err) + end + else + print("Unable to load tool file: " .. err) + end + end + end + TOOL = nil + + -- Examples + if (_OPTIONS["with-examples"]) then + local examples = os.matchdirs("../examples/*") + for k,v in pairs(examples) do + local dirName = v:match(".*/(.*)") + if (dirName ~= "bin" and dirName ~= "build") then + local f, err = loadfile(v .. "/build.lua") + if (f) then + EXAMPLE = {} + EXAMPLE.Directory = dirName + self:SetupInfoTable(EXAMPLE) + + f() + + local succeed, err = self:RegisterExample(EXAMPLE) + if (not succeed) then + print("Unable to register example: " .. err) + end + else + print("Unable to load example file: " .. err) + end + end + end + EXAMPLE = nil + end + + -- Once everything is registred, let's process all the tables + self.OrderedExamples = {} + self.OrderedExtLibs = {} + self.OrderedModules = {} + self.OrderedTools = {} + local tables = {self.Examples, self.ExtLibs, self.Modules, self.Tools} + local orderedTables = {self.OrderedExamples, self.OrderedExtLibs, self.OrderedModules, self.OrderedTools} + for k,projects in ipairs(tables) do + for projectId,projectTable in pairs(projects) do + self:Process(projectTable) + + table.insert(orderedTables[k], projectTable) + end + + table.sort(orderedTables[k], function (a, b) return a.Name < b.Name end) + end +end + +function NazaraBuild:RegisterAction(actionTable) + if (actionTable.Name == nil or type(actionTable.Name) ~= "string" or string.len(actionTable.Name) == 0) then + return false, "Invalid action name" + end + + local lowerCaseName = string.lower(actionTable.Name) + if (self.Actions[lowerCaseName] ~= nil) then + return false, "This action name is already in use" + end + + if (actionTable.Description == nil or type(actionTable.Description) ~= "string") then + return false, "Action description is invalid" + end + + if (string.len(actionTable.Description) == 0) then + return false, "Action description is empty" + end + + if (self.Actions[actionTable.name] ~= nil) then + return false, "Action name \"" .. actionTable.name .. " is already registred" + end + + if (actionTable.Function == nil or type(actionTable.Function) ~= "function") then + return false, "Action function is invalid" + end + + self.Actions[lowerCaseName] = actionTable + + newaction + { + trigger = lowerCaseName, + description = actionTable.Description, + execute = function () actionTable:Function() end + } + + return true +end + +function NazaraBuild:RegisterExample(exampleTable) + if (exampleTable.Name == nil or type(exampleTable.Name) ~= "string" or string.len(exampleTable.Name) == 0) then + return false, "Invalid example name" + end + + local lowerCaseName = exampleTable.Name:lower() + if (self.Examples[lowerCaseName] ~= nil) then + return false, "This library name is already in use" + end + + if (exampleTable.Files == nil or type(exampleTable.Files) ~= "table") then + return false, "Example files table is invalid" + end + + if (#exampleTable.Files == 0) then + return false, "This example has no files" + end + + local files = {} + for k, file in ipairs(exampleTable.Files) do + table.insert(files, "../examples/" .. exampleTable.Directory .. "/" .. file) + end + exampleTable.Files = files + + exampleTable.Type = "Example" + self.Examples[lowerCaseName] = exampleTable + return true +end + +function NazaraBuild:RegisterExternLibrary(libTable) + if (libTable.Name == nil or type(libTable.Name) ~= "string" or string.len(libTable.Name) == 0) then + return false, "Invalid library name" + end + + local lowerCaseName = libTable.Name:lower() + if (self.ExtLibs[lowerCaseName] ~= nil) then + return false, "This library name is already in use" + end + + if (libTable.Files == nil or type(libTable.Files) ~= "table") then + return false, "Invalid file table" + end + + if (#libTable.Files == 0) then + return false, "This library has no files" + end + + libTable.Type = "ExternLib" + self.ExtLibs[lowerCaseName] = libTable + return true +end + +function NazaraBuild:RegisterModule(moduleTable) + if (moduleTable.Name == nil or type(moduleTable.Name) ~= "string" or string.len(moduleTable.Name) == 0) then + return false, "Invalid module name" + end + + local lowerCaseName = moduleTable.Name:lower() + if (self.Modules[lowerCaseName] ~= nil) then + return false, "This module name is already in use" + end + + table.insert(moduleTable.Defines, "NAZARA_" .. moduleTable.Name:upper() .. "_BUILD") + table.insert(moduleTable.Files, "../include/Nazara/" .. moduleTable.Name .. "/**.hpp") + table.insert(moduleTable.Files, "../include/Nazara/" .. moduleTable.Name .. "/**.inl") + table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.hpp") + table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.inl") + table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.cpp") + + if (_OPTIONS["united"] and lowerCaseName ~= "core") then + table.insert(moduleTable.FilesExclusion, "../src/Nazara/" .. moduleTable.Name .. "/Debug/NewOverload.cpp") + end + + moduleTable.Type = "Module" + self.Modules[lowerCaseName] = moduleTable + return true +end + +function NazaraBuild:RegisterTool(toolTable) + if (toolTable.Name == nil or type(toolTable.Name) ~= "string" or string.len(toolTable.Name) == 0) then + return false, "Invalid tool name" + end + + local lowerCaseName = toolTable.Name:lower() + if (self.Tools[lowerCaseName] ~= nil) then + return false, "This tool name is already in use" + end + + if (toolTable.Directory == nil or type(toolTable.Directory) ~= "string" or string.len(toolTable.Directory) == 0) then + return false, "Invalid tool directory" + end + + if (toolTable.Kind == nil or type(toolTable.Kind) ~= "string" or string.len(toolTable.Kind) == 0) then + return false, "Invalid tool type" + end + + local lowerCaseKind = toolTable.Kind:lower() + if (lowerCaseKind == "library" or lowerCaseKind == "consoleapp" or lowerCaseKind == "windowapp") then + toolTable.Kind = lowerCaseKind + else + return false, "Invalid tool type" + end + + toolTable.Type = "Tool" + self.Tools[lowerCaseName] = toolTable + return true +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 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 + + if (not _OPTIONS["united"] 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 + else + local extLibTable = self.ExtLibs[library:lower()] + if (extLibTable) then + library = extLibTable.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") + 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 platform, fileTable in pairs(infoTable.OsFiles) 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(fileTable) do + table.insert(infoTable.Files, v) + end + else + for k,v in ipairs(fileTable) do + table.insert(infoTable.FilesExclusion, v) + end + end + end + infoTable.OsFiles = nil + + for platform, libraryTable in pairs(infoTable.OsLibraries) 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(libraryTable) do + table.insert(infoTable.Libraries, v) + end + end + end + infoTable.OsLibraries = nil +end + +function NazaraBuild:SetupInfoTable(infoTable) + infoTable.ConfigurationLibraries = {} + infoTable.ConfigurationLibraries.DebugStatic = {} + infoTable.ConfigurationLibraries.ReleaseStatic = {} + infoTable.ConfigurationLibraries.DebugDynamic = {} + infoTable.ConfigurationLibraries.ReleaseDynamic = {} + infoTable.Defines = {} + infoTable.Files = {} + infoTable.FilesExclusion = {} + infoTable.Flags = {} + infoTable.Includes = {} + infoTable.Libraries = {} + infoTable.OsFiles = {} + infoTable.OsLibraries = {} +end \ No newline at end of file From d0ff07d2624a2c216900284da9ba8643e1dc9106 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 20 Jan 2016 14:08:03 +0100 Subject: [PATCH 070/229] Build/SdkServer: Fix Console.cpp being included in the project Former-commit-id: 62d706654c398a60946282e112d7e139107ac745 --- build/scripts/tools/ndk_server.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index c94170dce..cbae533d6 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -23,12 +23,14 @@ TOOL.Files = { -- Exlude client-only files TOOL.FilesExclusion = { "../SDK/**/CameraComponent.*", + "../SDK/**/Console.*", "../SDK/**/GraphicsComponent.*", "../SDK/**/LightComponent.*", "../SDK/**/ListenerComponent.*", "../SDK/**/ListenerSystem.*", "../SDK/**/RenderSystem.*", - "../SDK/**/LuaInterface_Audio.*" + "../SDK/**/LuaAPI_Audio.*", + "../SDK/**/LuaAPI_Graphics.*", } TOOL.Libraries = { From 33f8e9775a1acae175c15d145bcf64141384b2f6 Mon Sep 17 00:00:00 2001 From: GigAnon Date: Wed, 20 Jan 2016 14:08:18 +0100 Subject: [PATCH 071/229] Updated .gitignore Added rule to exclude unit tests binaries Added rule to exclude more VS15 files Former-commit-id: 11ea17c814e2bdc8162f58ac8a3392d2d67c9c0d --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e029f58b2..ba135329b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Nazara build examples/bin/*.exe +tests/*.exe lib/* # Feature page @@ -28,6 +29,7 @@ build/**/*.sln build/**/*.vcxprojResolveAssemblyReference.cache build/**/*.nativecodeanalysis.all.xml build/**/*.nativecodeanalysis.xml +build/**/*.VC.opendb lib/*.exp # Compiled Object files From 3898421f2fb82cee8bfd1781162d6cd1c6d83fb7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 20 Jan 2016 14:08:43 +0100 Subject: [PATCH 072/229] Sdk/API: Begin Lua Binding Former-commit-id: b9be6bf7748296c3afc6fe1f32a1fd3fad6af008 --- SDK/include/NDK/LuaAPI.hpp | 33 +++++ SDK/include/NDK/LuaAPI.inl | 68 +++++++++ SDK/src/NDK/LuaAPI_Audio.cpp | 125 ++++++++++++++++ SDK/src/NDK/LuaAPI_Core.cpp | 280 +++++++++++++++++++++++++++++++++++ SDK/src/NDK/LuaAPI_Math.cpp | 135 +++++++++++++++++ 5 files changed, 641 insertions(+) create mode 100644 SDK/include/NDK/LuaAPI.hpp create mode 100644 SDK/include/NDK/LuaAPI.inl create mode 100644 SDK/src/NDK/LuaAPI_Audio.cpp create mode 100644 SDK/src/NDK/LuaAPI_Core.cpp create mode 100644 SDK/src/NDK/LuaAPI_Math.cpp diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp new file mode 100644 index 000000000..f248e28e8 --- /dev/null +++ b/SDK/include/NDK/LuaAPI.hpp @@ -0,0 +1,33 @@ +// 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_LUAINTERFACE_HPP +#define NDK_LUAINTERFACE_HPP + +#include + +namespace Nz +{ + class LuaInstance; +} + +namespace Ndk +{ + class NDK_API LuaAPI + { + public: + LuaAPI() = delete; + ~LuaAPI() = delete; + + static void Register_Audio(Nz::LuaInstance& instance); + static void Register_Core(Nz::LuaInstance& instance); + static void Register_Math(Nz::LuaInstance& instance); + }; +} + +#include + +#endif // NDK_LUAINTERFACE_HPP diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl new file mode 100644 index 000000000..205f29440 --- /dev/null +++ b/SDK/include/NDK/LuaAPI.inl @@ -0,0 +1,68 @@ +// 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 +#include +#include +#include + +namespace Nz +{ + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->forceMono = instance.CheckField("ForceMono", params->forceMono); + + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3d* vec, TypeTag) + { + switch (lua.GetType(index)) + { + case Nz::LuaType_Number: + if (index < 0 && index > -3) + lua.Error("Vector3 expected, three numbers are required to convert it"); + + vec->Set(lua.CheckNumber(index), lua.CheckNumber(index + 1), lua.CheckNumber(index + 2)); + return 3; + + case Nz::LuaType_Table: + vec->Set(lua.CheckField("x", index), lua.CheckField("y", index), lua.CheckField("z", index)); + return 3; + + default: + vec->Set(*(*static_cast(lua.CheckUserdata(index, "Vector3")))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3f* vec, TypeTag) + { + Vector3d vecDouble; + unsigned int ret = LuaImplQueryArg(lua, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) + { + instance.PushInstance("SoundBuffer", val); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d val, TypeTag) + { + instance.PushInstance("Vector3", val); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Vector3f val, TypeTag) + { + instance.PushInstance("Vector3", val); + return 1; + } +} diff --git a/SDK/src/NDK/LuaAPI_Audio.cpp b/SDK/src/NDK/LuaAPI_Audio.cpp new file mode 100644 index 000000000..07bb9bdec --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Audio.cpp @@ -0,0 +1,125 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Audio(Nz::LuaInstance& instance) + { + /*********************************** Nz::SoundBuffer **********************************/ + Nz::LuaClass soundBuffer("SoundBuffer"); + + soundBuffer.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::SoundBufferRef* { + return new Nz::SoundBufferRef(new Nz::SoundBuffer); + }); + + soundBuffer.SetMethod("Destroy", &Nz::SoundBuffer::Destroy); + soundBuffer.SetMethod("GetDuration", &Nz::SoundBuffer::GetDuration); + soundBuffer.SetMethod("GetFormat", &Nz::SoundBuffer::GetFormat); + soundBuffer.SetMethod("GetSampleCount", &Nz::SoundBuffer::GetSampleCount); + soundBuffer.SetMethod("GetSampleRate", &Nz::SoundBuffer::GetSampleRate); + soundBuffer.SetMethod("IsValid", &Nz::SoundBuffer::IsValid); + soundBuffer.SetMethod("LoadFromFile", &Nz::SoundBuffer::LoadFromFile, Nz::SoundBufferParams()); + + soundBuffer.SetStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported); + + // Manual + soundBuffer.SetMethod("Create", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int + { + int index = 1; + Nz::AudioFormat format = lua.Check(&index); + unsigned int sampleCount = lua.Check(&index); + unsigned int sampleRate = lua.Check(&index); + + std::size_t bufferSize = 0; + const char* buffer = lua.CheckString(index, &bufferSize); + NazaraAssert(buffer && bufferSize < sampleCount * sizeof(Nz::Int16), "Invalid buffer"); + + lua.PushBoolean(instance->Create(format, sampleCount, sampleRate, reinterpret_cast(buffer))); + return 1; + }); + + soundBuffer.SetMethod("GetSamples", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int + { + lua.PushString(reinterpret_cast(instance->GetSamples()), instance->GetSampleCount() * sizeof(Nz::Int16)); + return 1; + }); + + soundBuffer.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int { + Nz::StringStream stream("SoundBuffer("); + if (soundBuffer->IsValid()) + { + Nz::String filePath = soundBuffer->GetFilePath(); + if (!filePath.IsEmpty()) + stream << "File: " << filePath << ", "; + + stream << "Duration: " << soundBuffer->GetDuration() / 1000.f << "s"; + } + stream << ')'; + + lua.PushString(stream); + return 1; + }); + + soundBuffer.Register(instance); + + /*********************************** Nz::SoundEmitter **********************************/ + Nz::LuaClass soundEmitter("SoundEmitter"); + + soundEmitter.SetMethod("EnableLooping", &Nz::SoundEmitter::EnableLooping); + soundEmitter.SetMethod("EnableSpatialization", &Nz::SoundEmitter::EnableSpatialization); + soundEmitter.SetMethod("GetAttenuation", &Nz::SoundEmitter::GetAttenuation); + soundEmitter.SetMethod("GetDuration", &Nz::SoundEmitter::GetDuration); + soundEmitter.SetMethod("GetMinDistance", &Nz::SoundEmitter::GetMinDistance); + soundEmitter.SetMethod("GetPitch", &Nz::SoundEmitter::GetPitch); + soundEmitter.SetMethod("GetPlayingOffset", &Nz::SoundEmitter::GetPlayingOffset); + soundEmitter.SetMethod("GetPosition", &Nz::Sound::GetPosition); + soundEmitter.SetMethod("GetStatus", &Nz::SoundEmitter::GetStatus); + soundEmitter.SetMethod("GetVelocity", &Nz::Sound::GetVelocity); + soundEmitter.SetMethod("GetVolume", &Nz::SoundEmitter::GetVolume); + soundEmitter.SetMethod("IsLooping", &Nz::SoundEmitter::IsLooping); + soundEmitter.SetMethod("IsSpatialized", &Nz::SoundEmitter::IsSpatialized); + soundEmitter.SetMethod("Pause", &Nz::SoundEmitter::Pause); + soundEmitter.SetMethod("Play", &Nz::SoundEmitter::Play); + soundEmitter.SetMethod("SetAttenuation", &Nz::SoundEmitter::SetAttenuation); + soundEmitter.SetMethod("SetMinDistance", &Nz::SoundEmitter::SetMinDistance); + soundEmitter.SetMethod("SetPitch", &Nz::SoundEmitter::SetPitch); + soundEmitter.SetMethod("SetPosition", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetPosition); + soundEmitter.SetMethod("SetVelocity", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetVelocity); + soundEmitter.SetMethod("SetVolume", &Nz::SoundEmitter::SetVolume); + soundEmitter.SetMethod("Stop", &Nz::SoundEmitter::Stop); + + soundEmitter.Register(instance); + + /*********************************** Nz::Sound **********************************/ + Nz::LuaClass soundClass("Sound"); + soundClass.Inherit(soundEmitter); + + // Constructeur + soundClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Sound* { + return new Nz::Sound; + }); + + soundClass.SetMethod("GetBuffer", &Nz::Sound::GetBuffer); + soundClass.SetMethod("IsPlayable", &Nz::Sound::IsPlayable); + soundClass.SetMethod("IsPlaying", &Nz::Sound::IsPlaying); + soundClass.SetMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); + soundClass.SetMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); + + // Nz::Clock::__tostring (Manual) + soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int { + Nz::StringStream stream("Sound("); + if (const Nz::SoundBuffer* buffer = sound.GetBuffer()) + stream << buffer; + + stream << ')'; + + lua.PushString(stream); + return 1; + }); + + soundClass.Register(instance); + } +} diff --git a/SDK/src/NDK/LuaAPI_Core.cpp b/SDK/src/NDK/LuaAPI_Core.cpp new file mode 100644 index 000000000..8e626494a --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Core.cpp @@ -0,0 +1,280 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Core(Nz::LuaInstance& instance) + { + /*********************************** Nz::Clock **********************************/ + Nz::LuaClass clockClass("Clock"); + + // Constructeur + clockClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Clock* { + int index = 1; + return new Nz::Clock(lua.Check(&index, 0), lua.Check(&index, false)); + }); + + clockClass.SetMethod("GetMicroseconds", &Nz::Clock::GetMicroseconds); + clockClass.SetMethod("GetMilliseconds", &Nz::Clock::GetMilliseconds); + clockClass.SetMethod("GetSeconds", &Nz::Clock::GetSeconds); + clockClass.SetMethod("IsPaused", &Nz::Clock::IsPaused); + clockClass.SetMethod("Pause", &Nz::Clock::Pause); + clockClass.SetMethod("Restart", &Nz::Clock::Restart); + clockClass.SetMethod("Unpause", &Nz::Clock::Unpause); + + // Nz::Clock::__tostring (Manual) + clockClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& clock) -> int { + Nz::StringStream stream("Clock(Elapsed: "); + stream << clock.GetSeconds(); + stream << ", Paused: "; + stream << clock.IsPaused(); + stream << ')'; + + lua.PushString(stream); + return 1; + }); + + + clockClass.Register(instance); + + /********************************* Nz::Directory ********************************/ + Nz::LuaClass directoryClass("Directory"); + + // Constructeur + directoryClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Directory* { + unsigned int argCount = std::min(lua.GetStackTop(), 1U); + switch (argCount) + { + case 0: + { + return new Nz::Directory; + } + + case 1: + { + int index = 1; + return new Nz::Directory(lua.Check(&index)); + } + } + + return nullptr; + }); + + directoryClass.SetMethod("Close", &Nz::Directory::Close); + directoryClass.SetMethod("Exists", &Nz::Directory::Exists); + directoryClass.SetMethod("GetPath", &Nz::Directory::GetPath); + directoryClass.SetMethod("GetPattern", &Nz::Directory::GetPattern); + directoryClass.SetMethod("GetResultName", &Nz::Directory::GetResultName); + directoryClass.SetMethod("GetResultPath", &Nz::Directory::GetResultPath); + directoryClass.SetMethod("GetResultSize", &Nz::Directory::GetResultSize); + directoryClass.SetMethod("IsOpen", &Nz::Directory::IsOpen); + directoryClass.SetMethod("IsResultDirectory", &Nz::Directory::IsResultDirectory); + directoryClass.SetMethod("NextResult", &Nz::Directory::NextResult, true); + directoryClass.SetMethod("Open", &Nz::Directory::Open); + directoryClass.SetMethod("SetPath", &Nz::Directory::SetPath); + directoryClass.SetMethod("SetPattern", &Nz::Directory::SetPattern); + + directoryClass.SetStaticMethod("Copy", Nz::Directory::Copy); + directoryClass.SetStaticMethod("Create", Nz::Directory::Create); + directoryClass.SetStaticMethod("Exists", Nz::Directory::Exists); + directoryClass.SetStaticMethod("GetCurrent", Nz::Directory::GetCurrent); + directoryClass.SetStaticMethod("Remove", Nz::Directory::Remove); + directoryClass.SetStaticMethod("SetCurrent", Nz::Directory::SetCurrent); + + // Nz::Directory::__tostring (Manual) + directoryClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Directory& directory) -> int { + Nz::StringStream stream("Directory("); + stream << directory.GetPath(); + stream << ')'; + + lua.PushString(stream); + return 1; + }); + + + directoryClass.Register(instance); + + /*********************************** Nz::File ***********************************/ + Nz::LuaClass fileClass("File"); + + // Constructeur + fileClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::File* { + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + switch (argCount) + { + case 0: + { + return new Nz::File; + } + + case 1: + { + Nz::String filePath(lua.CheckString(1)); + + return new Nz::File(filePath); + } + + case 2: + { + Nz::String filePath(lua.CheckString(1)); + unsigned long openMode(lua.CheckInteger(2)); + + return new Nz::File(filePath, openMode); + } + } + + return nullptr; + }); + + fileClass.SetMethod("Close", &Nz::File::Close); + fileClass.SetMethod("Copy", &Nz::File::Copy); + fileClass.SetMethod("Delete", &Nz::File::Delete); + fileClass.SetMethod("EndOfFile", &Nz::File::EndOfFile); + fileClass.SetMethod("Exists", &Nz::File::Exists); + fileClass.SetMethod("GetCreationTime", &Nz::File::GetCreationTime); + fileClass.SetMethod("GetFileName", &Nz::File::GetFileName); + fileClass.SetMethod("GetLastAccessTime", &Nz::File::GetLastAccessTime); + fileClass.SetMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); + fileClass.SetMethod("IsOpen", &Nz::File::IsOpen); + fileClass.SetMethod("Rename", &Nz::File::GetLastWriteTime); + fileClass.SetMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); + fileClass.SetMethod("SetFile", &Nz::File::GetLastWriteTime); + + fileClass.SetMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + switch (argCount) + { + case 0: + { + bool _ret = file.Open(); + + lua.PushBoolean(_ret); + return 1; + } + + case 1: + { + if (lua.IsOfType(1, Nz::LuaType_Number)) + { + unsigned long openMode(lua.ToInteger(1)); + + bool _ret = file.Open(openMode); + + lua.PushBoolean(_ret); + return 1; + } + else if (lua.IsOfType(1, Nz::LuaType_String)) + { + Nz::String filePath(lua.ToString(1)); + + bool _ret = file.Open(filePath); + + lua.PushBoolean(_ret); + return 1; + } + } + + case 2: + { + Nz::String filePath(lua.CheckString(1)); + unsigned long openMode(lua.CheckInteger(2)); + + bool _ret = file.Open(filePath, openMode); + + lua.PushBoolean(_ret); + return 1; + } + } + + lua.Error("No matching overload for method Open"); + return 0; + }); + + fileClass.SetMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + switch (argCount) + { + case 1: + { + Nz::UInt64 offset(lua.CheckInteger(1)); + + bool _ret = file.SetCursorPos(offset); + + lua.PushBoolean(_ret); + return 1; + } + + case 2: + { + Nz::CursorPosition pos(static_cast(lua.CheckInteger(1))); + Nz::Int64 offset(lua.CheckInteger(2)); + + bool _ret = file.SetCursorPos(pos, offset); + + lua.PushBoolean(_ret); + return 1; + } + } + + lua.Error("No matching overload for method SetCursorPos"); + return 0; + }); + + // Nz::File::Read (Manual) + fileClass.SetMethod("Read", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + int length = lua.CheckInteger(1); + lua.ArgCheck(length > 0, 1, "length must be positive"); + + std::unique_ptr buffer(new char[length]); + std::size_t readLength = file.Read(buffer.get(), length); + + lua.PushString(Nz::String(buffer.get(), readLength)); + return 1; + }); + + // Nz::File::ReadLine (Manual) + fileClass.SetMethod("ReadLine", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + int length = lua.CheckInteger(1, 0); + lua.PushString(file.ReadLine(length)); + return 1; + }); + + // Nz::File::__tostring (Manual) + fileClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + Nz::StringStream stream("File("); + if (file.IsOpen()) + stream << "Path: " << file.GetPath(); + + stream << ')'; + + lua.PushString(stream); + return 1; + }); + + + fileClass.Register(instance); + + // Énumérations de la classe Nz::File + fileClass.PushGlobalTable(instance); + + // Nz::File::CursorPosition + instance.SetField("AtBegin", Nz::CursorPosition_AtBegin); + instance.SetField("AtCurrent", Nz::CursorPosition_AtCurrent); + instance.SetField("AtEnd", Nz::CursorPosition_AtEnd); + + // Nz::File::OpenMode + instance.SetField("Append", Nz::OpenMode_Append); + instance.SetField("NotOpen", Nz::OpenMode_NotOpen); + instance.SetField("Lock", Nz::OpenMode_Lock); + instance.SetField("ReadOnly", Nz::OpenMode_ReadOnly); + instance.SetField("ReadWrite", Nz::OpenMode_ReadWrite); + instance.SetField("Text", Nz::OpenMode_Text); + instance.SetField("Truncate", Nz::OpenMode_Truncate); + instance.SetField("WriteOnly", Nz::OpenMode_WriteOnly); + + instance.Pop(); + } +} diff --git a/SDK/src/NDK/LuaAPI_Math.cpp b/SDK/src/NDK/LuaAPI_Math.cpp new file mode 100644 index 000000000..de6b35b22 --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Math.cpp @@ -0,0 +1,135 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Math(Nz::LuaInstance& instance) + { + /*********************************** Nz::Vector3 **********************************/ + Nz::LuaClass vectorClass("Vector3"); + + vectorClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Vector3d* { + unsigned int argCount = std::min(lua.GetStackTop(), 3U); + switch (argCount) + { + case 0: + case 3: + return new Nz::Vector3d(lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0), lua.CheckNumber(3, 0.0)); + + case 1: + { + if (lua.IsOfType(1, Nz::LuaType_Number)) + return new Nz::Vector3d(lua.CheckNumber(1), *static_cast(lua.ToUserdata(1))); + else if (lua.IsOfType(1, "Vector2")) + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); + else if (lua.IsOfType(1, "Vector3")) + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); + + break; + } + + case 2: + { + if (lua.IsOfType(1, Nz::LuaType_Number)) + return new Nz::Vector3d(lua.CheckNumber(1), *static_cast(lua.CheckUserdata(1, "Vector2"))); + else if (lua.IsOfType(1, "Vector2")) + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1))), lua.CheckNumber(2)); + + break; + } + } + + lua.Error("No matching overload for constructor"); + return nullptr; + }); + + vectorClass.SetMethod("__tostring", &Nz::Vector3d::ToString); + + vectorClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) + { + switch (lua.GetType(1)) + { + case Nz::LuaType_Number: + lua.Push(instance[lua.CheckInteger(1)]); + return true; + + case Nz::LuaType_String: + { + std::size_t length; + const char* xyz = lua.CheckString(1, &length); + + if (length != 1) + break; + + switch (xyz[0]) + { + case 'x': + lua.Push(instance.x); + return true; + + case 'y': + lua.Push(instance.y); + return true; + + case 'z': + lua.Push(instance.z); + return true; + } + break; + } + } + + return false; + }); + + vectorClass.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) + { + switch (lua.GetType(1)) + { + case Nz::LuaType_Number: + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 3) + return false; + + instance[index] = lua.CheckNumber(2); + return true; + } + + case Nz::LuaType_String: + { + std::size_t length; + const char* xyz = lua.CheckString(1, &length); + + if (length != 1) + break; + + double value = lua.CheckNumber(2); + + switch (xyz[0]) + { + case 'x': + instance.x = value; + return true; + + case 'y': + instance.y = value; + return true; + + case 'z': + instance.z = value; + return true; + } + break; + } + } + + return false; + }); + + vectorClass.Register(instance); + } +} From 83b365f1397c7862913836beb9473a1bd8d74143 Mon Sep 17 00:00:00 2001 From: GigAnon Date: Wed, 20 Jan 2016 17:05:57 +0100 Subject: [PATCH 073/229] Lua Binding - Added Lua binding for Nz::MD5Hash & Nz::AbstractHash to LuaAPI_Core (to be tested) - Fixed a comment in LuaAPI_Audio Former-commit-id: d80eec6616b7dad31e2fbbbe4ff6f5d1d28b67e4 --- SDK/src/NDK/LuaAPI_Audio.cpp | 2 +- SDK/src/NDK/LuaAPI_Core.cpp | 64 ++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/SDK/src/NDK/LuaAPI_Audio.cpp b/SDK/src/NDK/LuaAPI_Audio.cpp index 07bb9bdec..2865b956a 100644 --- a/SDK/src/NDK/LuaAPI_Audio.cpp +++ b/SDK/src/NDK/LuaAPI_Audio.cpp @@ -108,7 +108,7 @@ namespace Ndk soundClass.SetMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); soundClass.SetMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); - // Nz::Clock::__tostring (Manual) + // Nz::Sound::__tostring (Manual) soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int { Nz::StringStream stream("Sound("); if (const Nz::SoundBuffer* buffer = sound.GetBuffer()) diff --git a/SDK/src/NDK/LuaAPI_Core.cpp b/SDK/src/NDK/LuaAPI_Core.cpp index 8e626494a..0725627ee 100644 --- a/SDK/src/NDK/LuaAPI_Core.cpp +++ b/SDK/src/NDK/LuaAPI_Core.cpp @@ -4,10 +4,74 @@ #include #include +#include + namespace Ndk { void LuaAPI::Register_Core(Nz::LuaInstance& instance) { + /******************************** Nz::AbstractHash *******************************/ + Nz::LuaClass abstractHashClass("AbstractHash"); + + abstractHashClass.SetMethod("__tostring", + [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int + { + Nz::StringStream strStrm("Nz::AbstractHash("); + + strStrm << "Hash type: " << hash.GetHashName() << ", "; + strStrm << "Digest size: " << hash.GetDigestLength() << ")"; + + lua.PushString(strStrm); + return 1; + }); + + abstractHashClass.SetMethod("Append", + [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int + { + size_t dataLength = 0; + const Nz::UInt8* data = reinterpret_cast(lua.CheckString(1, &dataLength)); + + hash.Append(data, dataLength); + + return 0; + }); + + abstractHashClass.SetMethod("Begin", &Nz::AbstractHash::Begin); + + abstractHashClass.SetMethod("End", + [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int + { + Nz::ByteArray data(hash.End()); // Exceptions? What's the expected behavior of that method? + + lua.PushString(data.ToString()); + return 1; + }); + + abstractHashClass.SetMethod("GetDigestLength", &Nz::AbstractHash::GetDigestLength); + abstractHashClass.SetMethod("GetHashName", + [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int + { + Nz::String hashName(hash.GetHashName()); + lua.PushString(hashName); + return 1; + }); + + abstractHashClass.Register(instance); + + /********************************** Nz::HashMD5 **********************************/ + Nz::LuaClass hashMD5Class("HashMD5"); + hashMD5Class.Inherit(abstractHashClass); + + hashMD5Class.SetConstructor( + [](Nz::LuaInstance& lua) -> Nz::HashMD5* + { + if(std::min(lua.GetStackTop(), 1U) == 0) + return new Nz::HashMD5(); + return nullptr; + }); + + hashMD5Class.Register(instance); + /*********************************** Nz::Clock **********************************/ Nz::LuaClass clockClass("Clock"); From 95f6977c1ff1a4bf2e5cee1190b635ce26f1b6d5 Mon Sep 17 00:00:00 2001 From: GigAnon Date: Wed, 20 Jan 2016 18:34:31 +0100 Subject: [PATCH 074/229] Vector2 Lua Binding Added Nz::Vector2 Lua binding Former-commit-id: 727ad086fe62ce131ffdbc24ce17d020cd0fede7 --- SDK/src/NDK/LuaAPI_Core.cpp | 3 +- SDK/src/NDK/LuaAPI_Math.cpp | 122 +++++++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 8 deletions(-) diff --git a/SDK/src/NDK/LuaAPI_Core.cpp b/SDK/src/NDK/LuaAPI_Core.cpp index 0725627ee..ae2172988 100644 --- a/SDK/src/NDK/LuaAPI_Core.cpp +++ b/SDK/src/NDK/LuaAPI_Core.cpp @@ -41,13 +41,14 @@ namespace Ndk abstractHashClass.SetMethod("End", [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int { - Nz::ByteArray data(hash.End()); // Exceptions? What's the expected behavior of that method? + Nz::ByteArray data(hash.End()); lua.PushString(data.ToString()); return 1; }); abstractHashClass.SetMethod("GetDigestLength", &Nz::AbstractHash::GetDigestLength); + abstractHashClass.SetMethod("GetHashName", [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int { diff --git a/SDK/src/NDK/LuaAPI_Math.cpp b/SDK/src/NDK/LuaAPI_Math.cpp index de6b35b22..053ff6f10 100644 --- a/SDK/src/NDK/LuaAPI_Math.cpp +++ b/SDK/src/NDK/LuaAPI_Math.cpp @@ -8,10 +8,118 @@ namespace Ndk { void LuaAPI::Register_Math(Nz::LuaInstance& instance) { - /*********************************** Nz::Vector3 **********************************/ - Nz::LuaClass vectorClass("Vector3"); + /*********************************** Nz::Vector2 **********************************/ + Nz::LuaClass vector2dClass("Vector2"); - vectorClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Vector3d* { + vector2dClass.SetConstructor( + [](Nz::LuaInstance& lua) -> Nz::Vector2d* + { + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + switch (argCount) + { + case 0: + case 2: + return new Nz::Vector2d(lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0)); + + case 1: + { + if (lua.IsOfType(1, Nz::LuaType_Number)) + return new Nz::Vector2d(lua.CheckNumber(1)); + else if (lua.IsOfType(1, "Vector2")) + return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); + + break; + } + } + + lua.Error("No matching overload for Vector2 constructor"); + return nullptr; + }); + + vector2dClass.SetMethod("__tostring", &Nz::Vector2d::ToString); + + vector2dClass.SetGetter( + [](Nz::LuaInstance& lua, Nz::Vector2d& instance) + { + switch (lua.GetType(1)) + { + case Nz::LuaType_Number: + lua.Push(instance[lua.CheckInteger(1)]); + return true; + + case Nz::LuaType_String: + { + std::size_t length; + const char* xy = lua.CheckString(1, &length); + + if (length != 1) + break; + + switch (xy[0]) + { + case 'x': + lua.Push(instance.x); + return true; + + case 'y': + lua.Push(instance.y); + return true; + } + break; + } + } + + return false; + }); + + vector2dClass.SetSetter( + [](Nz::LuaInstance& lua, Nz::Vector2d& instance) + { + switch (lua.GetType(1)) + { + case Nz::LuaType_Number: + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 2) + return false; + + instance[index] = lua.CheckNumber(2); + return true; + } + + case Nz::LuaType_String: + { + std::size_t length; + const char* xy = lua.CheckString(1, &length); + + if (length != 1) + break; + + double value = lua.CheckNumber(2); + + switch (xy[0]) + { + case 'x': + instance.x = value; + return true; + + case 'y': + instance.y = value; + return true; + } + break; + } + } + + return false; + }); + + vector2dClass.Register(instance); + + /*********************************** Nz::Vector3 **********************************/ + Nz::LuaClass vector3dClass("Vector3"); + + vector3dClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Vector3d* { unsigned int argCount = std::min(lua.GetStackTop(), 3U); switch (argCount) { @@ -46,9 +154,9 @@ namespace Ndk return nullptr; }); - vectorClass.SetMethod("__tostring", &Nz::Vector3d::ToString); + vector3dClass.SetMethod("__tostring", &Nz::Vector3d::ToString); - vectorClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) + vector3dClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) { switch (lua.GetType(1)) { @@ -85,7 +193,7 @@ namespace Ndk return false; }); - vectorClass.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) + vector3dClass.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) { switch (lua.GetType(1)) { @@ -130,6 +238,6 @@ namespace Ndk return false; }); - vectorClass.Register(instance); + vector3dClass.Register(instance); } } From 14f4291c7c448d11c3064341012dd0b82187f007 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Jan 2016 13:05:43 +0100 Subject: [PATCH 075/229] Lua/LuaClass: Fix arguments for methods Former-commit-id: fc3ec0b3f47185edb74abe1eb54af8722844a6f5 --- include/Nazara/Lua/LuaClass.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index ea86b6f1a..b2bbdbc3e 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -405,6 +405,7 @@ namespace Nz if (it != info->instanceGetters.end()) instance = it->second(lua); } + lua.Pop(2); } lua.Remove(1); //< Remove the instance from the Lua stack From 9d210eb2ff01773674707e8bee7f0537b51b50b4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Jan 2016 13:06:44 +0100 Subject: [PATCH 076/229] Lua/LuaInstance: Cleanup Former-commit-id: 031e810caf968700d5bd8b2c51698f110c6559af --- include/Nazara/Lua/LuaInstance.inl | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 1ce27b48c..77155cba0 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -45,18 +45,14 @@ namespace Nz std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) { using UnderlyingT = std::underlying_type_t; - *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag())); - - return 1; + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); } template std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { using UnderlyingT = std::underlying_type_t; - *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag())); - - return 1; + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); } template @@ -98,7 +94,6 @@ namespace Nz std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { using SignedT = std::make_signed_t; - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); } @@ -149,7 +144,6 @@ namespace Nz std::enable_if_t::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) { using EnumT = typename std::underlying_type::type; - return LuaImplReplyVal(instance, static_cast(val), TypeTag()); } From 642f139da97bc42f93b65fccf233306193da9630 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Jan 2016 13:07:05 +0100 Subject: [PATCH 077/229] Sdk/LuaAPI: Improve error check Former-commit-id: 5c33dd47c3da1c5957704272405dcd6c26117c0f --- SDK/src/NDK/LuaAPI_Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/src/NDK/LuaAPI_Audio.cpp b/SDK/src/NDK/LuaAPI_Audio.cpp index 07bb9bdec..12f9192a8 100644 --- a/SDK/src/NDK/LuaAPI_Audio.cpp +++ b/SDK/src/NDK/LuaAPI_Audio.cpp @@ -35,7 +35,7 @@ namespace Ndk std::size_t bufferSize = 0; const char* buffer = lua.CheckString(index, &bufferSize); - NazaraAssert(buffer && bufferSize < sampleCount * sizeof(Nz::Int16), "Invalid buffer"); + lua.ArgCheck(buffer && bufferSize < sampleCount * sizeof(Nz::Int16), index, "Invalid buffer"); lua.PushBoolean(instance->Create(format, sampleCount, sampleRate, reinterpret_cast(buffer))); return 1; From 1ef85ae8061715767261bb5814dc998f1677c584 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Jan 2016 13:07:37 +0100 Subject: [PATCH 078/229] Sdk/LuAPI: Bind Nz::Stream class Former-commit-id: 286ecbd79b25b30d17055640e1c792906f434525 --- SDK/src/NDK/LuaAPI_Core.cpp | 68 +++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/SDK/src/NDK/LuaAPI_Core.cpp b/SDK/src/NDK/LuaAPI_Core.cpp index 8e626494a..16d7c9b3c 100644 --- a/SDK/src/NDK/LuaAPI_Core.cpp +++ b/SDK/src/NDK/LuaAPI_Core.cpp @@ -29,7 +29,7 @@ namespace Ndk clockClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& clock) -> int { Nz::StringStream stream("Clock(Elapsed: "); stream << clock.GetSeconds(); - stream << ", Paused: "; + stream << "s, Paused: "; stream << clock.IsPaused(); stream << ')'; @@ -97,8 +97,53 @@ namespace Ndk directoryClass.Register(instance); + /*********************************** Nz::Stream ***********************************/ + Nz::LuaClass streamClass("Stream"); + + streamClass.SetMethod("EnableTextMode", &Nz::Stream::EnableTextMode); + streamClass.SetMethod("Flush", &Nz::Stream::Flush); + streamClass.SetMethod("GetCursorPos", &Nz::Stream::GetCursorPos); + streamClass.SetMethod("GetDirectory", &Nz::Stream::GetDirectory); + streamClass.SetMethod("GetPath", &Nz::Stream::GetPath); + streamClass.SetMethod("GetOpenMode", &Nz::Stream::GetOpenMode); + streamClass.SetMethod("GetStreamOptions", &Nz::Stream::GetStreamOptions); + streamClass.SetMethod("GetSize", &Nz::Stream::GetSize); + streamClass.SetMethod("ReadLine", &Nz::Stream::ReadLine, 0U); + streamClass.SetMethod("IsReadable", &Nz::Stream::IsReadable); + streamClass.SetMethod("IsSequential", &Nz::Stream::IsSequential); + streamClass.SetMethod("IsTextModeEnabled", &Nz::Stream::IsTextModeEnabled); + streamClass.SetMethod("IsWritable", &Nz::Stream::IsWritable); + streamClass.SetMethod("SetCursorPos", &Nz::Stream::SetCursorPos); + + streamClass.SetMethod("Read", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { + int length = lua.CheckInteger(1); + lua.ArgCheck(length > 0, 1, "length must be positive"); + + std::unique_ptr buffer(new char[length]); + std::size_t readLength = stream.Read(buffer.get(), length); + + lua.PushString(Nz::String(buffer.get(), readLength)); + return 1; + }); + + streamClass.SetMethod("Write", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { + int index = 1; + + std::size_t bufferSize = 0; + const char* buffer = lua.CheckString(index, &bufferSize); + + if (stream.IsTextModeEnabled()) + lua.Push(stream.Write(Nz::String(buffer, bufferSize))); + else + lua.Push(stream.Write(buffer, bufferSize)); + return 1; + }); + + streamClass.Register(instance); + /*********************************** Nz::File ***********************************/ Nz::LuaClass fileClass("File"); + fileClass.Inherit(streamClass); // Constructeur fileClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::File* { @@ -223,26 +268,6 @@ namespace Ndk return 0; }); - // Nz::File::Read (Manual) - fileClass.SetMethod("Read", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { - int length = lua.CheckInteger(1); - lua.ArgCheck(length > 0, 1, "length must be positive"); - - std::unique_ptr buffer(new char[length]); - std::size_t readLength = file.Read(buffer.get(), length); - - lua.PushString(Nz::String(buffer.get(), readLength)); - return 1; - }); - - // Nz::File::ReadLine (Manual) - fileClass.SetMethod("ReadLine", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { - int length = lua.CheckInteger(1, 0); - lua.PushString(file.ReadLine(length)); - return 1; - }); - - // Nz::File::__tostring (Manual) fileClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { Nz::StringStream stream("File("); if (file.IsOpen()) @@ -254,7 +279,6 @@ namespace Ndk return 1; }); - fileClass.Register(instance); // Énumérations de la classe Nz::File From 04aac4363f0a0ebb1c4fc02c38fcd37421526c02 Mon Sep 17 00:00:00 2001 From: GigAnon Date: Thu, 21 Jan 2016 14:12:20 +0100 Subject: [PATCH 079/229] Lua binding update - Added files & Register_X methods for modules Graphics, Renderer and Utility - Added Nz::AbstractImage binding (WIP) Former-commit-id: 91fd641c7676c12034e5f702bd3ba45e2a826263 --- SDK/include/NDK/LuaAPI.hpp | 3 + SDK/src/NDK/LuaAPI_Graphics.cpp | 15 ++++ SDK/src/NDK/LuaAPI_Renderer.cpp | 147 ++++++++++++++++++++++++++++++++ SDK/src/NDK/LuaAPI_Utility.cpp | 14 +++ 4 files changed, 179 insertions(+) create mode 100644 SDK/src/NDK/LuaAPI_Graphics.cpp create mode 100644 SDK/src/NDK/LuaAPI_Renderer.cpp create mode 100644 SDK/src/NDK/LuaAPI_Utility.cpp diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index f248e28e8..8965229e2 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -25,6 +25,9 @@ namespace Ndk static void Register_Audio(Nz::LuaInstance& instance); static void Register_Core(Nz::LuaInstance& instance); static void Register_Math(Nz::LuaInstance& instance); + static void Register_Utility(Nz::LuaInstance& instance); + static void Register_Graphics(Nz::LuaInstance& instance); + static void Register_Renderer(Nz::LuaInstance& instance); }; } diff --git a/SDK/src/NDK/LuaAPI_Graphics.cpp b/SDK/src/NDK/LuaAPI_Graphics.cpp new file mode 100644 index 000000000..685e64cb5 --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Graphics.cpp @@ -0,0 +1,15 @@ +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Graphics(Nz::LuaInstance& instance) + { + + } +} \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_Renderer.cpp b/SDK/src/NDK/LuaAPI_Renderer.cpp new file mode 100644 index 000000000..e61d10af1 --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Renderer.cpp @@ -0,0 +1,147 @@ +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Renderer(Nz::LuaInstance& instance) + { + /*********************************** Nz::AbstractImage **********************************/ + Nz::LuaClass abstractImage("AbstractImage"); + + abstractImage.SetMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); + abstractImage.SetMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); + abstractImage.SetMethod("GetFormat", &Nz::AbstractImage::GetFormat); + abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); + abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); + abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); + /*abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0));*/ // Need to add Nz::Vector3ui to auto binding mecanism, or do it by hand + abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); + abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); + abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); + abstractImage.SetMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); + + abstractImage.SetMethod("GetMemoryUsage", + [](Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + { + unsigned int memory = 0; + + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + if (argCount == 1 && lua.IsOfType(1, Nz::LuaType_Number)) + memory = abstractImage->GetMemoryUsage(static_cast(lua.CheckInteger(1))); // Maybe do a range check instead of casting like a savage? + else + memory = abstractImage->GetMemoryUsage(); + + lua.PushInteger(memory); + return 1; + }); + + abstractImage.SetMethod("__tostring", + [](Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + { + lua.PushString(Nz::StringStream("AbstractImage()")); + return 1; + }); + + abstractImage.SetMethod("Update", + [](Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + + if (argCount < 1) + { + lua.Error("No matching overload for method AbstractImage::Update"); + return 0; + } + + bool rValue; + const Nz::UInt8* pixels = reinterpret_cast(lua.CheckString(1)); + + if (argCount == 1) + rValue = abstractImage->Update(pixels); + else + { + // Three possible overloads, based on second argument type + if (lua.IsOfType(2, Nz::LuaType_Number)) // Overload #1 + { + /* Prototype is: + virtual bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + */ + + unsigned int srcWidth = static_cast(lua.CheckInteger(2)); // Range check? + unsigned int srcHeight = 0; + Nz::UInt8 level = 0; + + if (argCount >= 3) + { + srcHeight = static_cast(lua.CheckInteger(3)); // Range check? + if (argCount >= 4) + level = static_cast(lua.CheckInteger(3)); // Range check? + } + + rValue = abstractImage->Update(pixels, srcWidth, srcHeight, level); + } + else if (lua.IsOfType(2, "Box")) // Overload #2 + { + /* Prototype is: + virtual bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + */ + + Nz::Boxui box (*(static_cast(lua.ToUserdata(2)))); // Placeholder. Ask Lynix about templates & bindings. Nz::Box has to be bound, too. + unsigned int srcWidth = 0; + unsigned int srcHeight = 0; + Nz::UInt8 level = 0; + + if (argCount >= 3) + { + srcWidth = static_cast(lua.CheckInteger(3)); // Range check? + if (argCount >= 4) + { + srcHeight = static_cast(lua.CheckInteger(4)); // Range check? + if (argCount >= 5) + level = static_cast(lua.CheckInteger(5)); // Range check? + } + } + rValue = abstractImage->Update(pixels, box, srcWidth, srcHeight, level); + } + else if (lua.IsOfType(2, "Rect")) // Overload #3 + { + /* Prototype is: + virtual bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + */ + + Nz::Rectui rect(*(static_cast(lua.ToUserdata(2)))); // Placeholder. See comment at box declaration in overload #2 + unsigned int z = 0; + unsigned int srcWidth = 0; + unsigned int srcHeight = 0; + Nz::UInt8 level = 0; + + if (argCount >= 3) + { + z = static_cast(lua.CheckInteger(3)); // Range check? + if (argCount >= 4) + { + srcWidth = static_cast(lua.CheckInteger(4)); // Range check? + if (argCount >= 5) + { + srcHeight = static_cast(lua.CheckInteger(5)); // Range check? + if (argCount >= 6) + level = static_cast(lua.CheckInteger(6)); // Range check? + } + } + } + rValue = abstractImage->Update(pixels, rect, z, srcWidth, srcHeight, level); + } + } + + lua.PushBoolean(rValue); + return 1; + }); + + abstractImage.Register(instance); + } +} \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_Utility.cpp b/SDK/src/NDK/LuaAPI_Utility.cpp new file mode 100644 index 000000000..0f6bfb1cd --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Utility.cpp @@ -0,0 +1,14 @@ +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Utility(Nz::LuaInstance& instance) + { + } +} \ No newline at end of file From 69a1be70badbae2ab03176a0edb1d246f0eb7c1b Mon Sep 17 00:00:00 2001 From: GigAnon Date: Thu, 21 Jan 2016 18:54:01 +0100 Subject: [PATCH 080/229] Lua Binding update - Added range check on various casts (ranged_cast routine needs to be moved somewhere else) - Added Nz::Vector3ui type to auto-bind system Former-commit-id: 3ec773b26d9cc85e40879c011cad0fb2a3d05571 --- SDK/include/NDK/LuaAPI.inl | 16 ++++++++++++++++ SDK/src/NDK/LuaAPI_Renderer.cpp | 33 +++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 205f29440..79c1feb86 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -48,6 +48,16 @@ namespace Nz return ret; } + inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3ui* vec, TypeTag) + { + Vector3d vecDouble; + unsigned int ret = LuaImplQueryArg(lua, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) { instance.PushInstance("SoundBuffer", val); @@ -65,4 +75,10 @@ namespace Nz instance.PushInstance("Vector3", val); return 1; } + + inline int LuaImplReplyVal(const LuaInstance& instance, Vector3ui val, TypeTag) + { + instance.PushInstance("Vector3", val); + return 1; + } } diff --git a/SDK/src/NDK/LuaAPI_Renderer.cpp b/SDK/src/NDK/LuaAPI_Renderer.cpp index e61d10af1..c088a5151 100644 --- a/SDK/src/NDK/LuaAPI_Renderer.cpp +++ b/SDK/src/NDK/LuaAPI_Renderer.cpp @@ -1,3 +1,4 @@ +// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -6,6 +7,14 @@ #include #include +#include + +// WIP: I don't know where to put it... +template T ranged_cast(long long a, T high = std::numeric_limits::max(), T low = std::numeric_limits::min()) +{ + return static_cast(std::min(static_cast(high), std::max(a, static_cast(low)))); +} + namespace Ndk { void LuaAPI::Register_Renderer(Nz::LuaInstance& instance) @@ -19,7 +28,7 @@ namespace Ndk abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); - /*abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0));*/ // Need to add Nz::Vector3ui to auto binding mecanism, or do it by hand + abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); @@ -32,7 +41,7 @@ namespace Ndk unsigned int argCount = std::min(lua.GetStackTop(), 2U); if (argCount == 1 && lua.IsOfType(1, Nz::LuaType_Number)) - memory = abstractImage->GetMemoryUsage(static_cast(lua.CheckInteger(1))); // Maybe do a range check instead of casting like a savage? + memory = abstractImage->GetMemoryUsage(ranged_cast(lua.CheckInteger(1))); else memory = abstractImage->GetMemoryUsage(); @@ -72,15 +81,15 @@ namespace Ndk virtual bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) */ - unsigned int srcWidth = static_cast(lua.CheckInteger(2)); // Range check? + unsigned int srcWidth = ranged_cast(lua.CheckInteger(2)); unsigned int srcHeight = 0; Nz::UInt8 level = 0; if (argCount >= 3) { - srcHeight = static_cast(lua.CheckInteger(3)); // Range check? + srcHeight = ranged_cast(lua.CheckInteger(3)); if (argCount >= 4) - level = static_cast(lua.CheckInteger(3)); // Range check? + level = ranged_cast(lua.CheckInteger(3)); } rValue = abstractImage->Update(pixels, srcWidth, srcHeight, level); @@ -98,12 +107,12 @@ namespace Ndk if (argCount >= 3) { - srcWidth = static_cast(lua.CheckInteger(3)); // Range check? + srcWidth = ranged_cast(lua.CheckInteger(3)); if (argCount >= 4) { - srcHeight = static_cast(lua.CheckInteger(4)); // Range check? + srcHeight = ranged_cast(lua.CheckInteger(4)); if (argCount >= 5) - level = static_cast(lua.CheckInteger(5)); // Range check? + level = ranged_cast(lua.CheckInteger(5)); } } rValue = abstractImage->Update(pixels, box, srcWidth, srcHeight, level); @@ -122,15 +131,15 @@ namespace Ndk if (argCount >= 3) { - z = static_cast(lua.CheckInteger(3)); // Range check? + z = ranged_cast(lua.CheckInteger(3)); if (argCount >= 4) { - srcWidth = static_cast(lua.CheckInteger(4)); // Range check? + srcWidth = ranged_cast(lua.CheckInteger(4)); if (argCount >= 5) { - srcHeight = static_cast(lua.CheckInteger(5)); // Range check? + srcHeight = ranged_cast(lua.CheckInteger(5)); if (argCount >= 6) - level = static_cast(lua.CheckInteger(6)); // Range check? + level = ranged_cast(lua.CheckInteger(6)); } } } From 8bfd879d8726cf266e502f501a2ce232f7f34185 Mon Sep 17 00:00:00 2001 From: GigAnon Date: Thu, 21 Jan 2016 20:12:37 +0100 Subject: [PATCH 081/229] Nz::ranged_cast - Moved ranged_cast template function to namespace Nz in file LuaInstance.hpp - Added comments Former-commit-id: 9af0a680b693208e582eb4edbe5a65f996d70a4a --- SDK/src/NDK/LuaAPI_Renderer.cpp | 30 +++++++++++------------------- include/Nazara/Lua/LuaInstance.hpp | 9 +++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/SDK/src/NDK/LuaAPI_Renderer.cpp b/SDK/src/NDK/LuaAPI_Renderer.cpp index c088a5151..5c801748a 100644 --- a/SDK/src/NDK/LuaAPI_Renderer.cpp +++ b/SDK/src/NDK/LuaAPI_Renderer.cpp @@ -7,14 +7,6 @@ #include #include -#include - -// WIP: I don't know where to put it... -template T ranged_cast(long long a, T high = std::numeric_limits::max(), T low = std::numeric_limits::min()) -{ - return static_cast(std::min(static_cast(high), std::max(a, static_cast(low)))); -} - namespace Ndk { void LuaAPI::Register_Renderer(Nz::LuaInstance& instance) @@ -41,7 +33,7 @@ namespace Ndk unsigned int argCount = std::min(lua.GetStackTop(), 2U); if (argCount == 1 && lua.IsOfType(1, Nz::LuaType_Number)) - memory = abstractImage->GetMemoryUsage(ranged_cast(lua.CheckInteger(1))); + memory = abstractImage->GetMemoryUsage(Nz::ranged_cast(lua.CheckInteger(1))); else memory = abstractImage->GetMemoryUsage(); @@ -81,15 +73,15 @@ namespace Ndk virtual bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) */ - unsigned int srcWidth = ranged_cast(lua.CheckInteger(2)); + unsigned int srcWidth = Nz::ranged_cast(lua.CheckInteger(2)); unsigned int srcHeight = 0; Nz::UInt8 level = 0; if (argCount >= 3) { - srcHeight = ranged_cast(lua.CheckInteger(3)); + srcHeight = Nz::ranged_cast(lua.CheckInteger(3)); if (argCount >= 4) - level = ranged_cast(lua.CheckInteger(3)); + level = Nz::ranged_cast(lua.CheckInteger(3)); } rValue = abstractImage->Update(pixels, srcWidth, srcHeight, level); @@ -107,12 +99,12 @@ namespace Ndk if (argCount >= 3) { - srcWidth = ranged_cast(lua.CheckInteger(3)); + srcWidth = Nz::ranged_cast(lua.CheckInteger(3)); if (argCount >= 4) { - srcHeight = ranged_cast(lua.CheckInteger(4)); + srcHeight = Nz::ranged_cast(lua.CheckInteger(4)); if (argCount >= 5) - level = ranged_cast(lua.CheckInteger(5)); + level = Nz::ranged_cast(lua.CheckInteger(5)); } } rValue = abstractImage->Update(pixels, box, srcWidth, srcHeight, level); @@ -131,15 +123,15 @@ namespace Ndk if (argCount >= 3) { - z = ranged_cast(lua.CheckInteger(3)); + z = Nz::ranged_cast(lua.CheckInteger(3)); if (argCount >= 4) { - srcWidth = ranged_cast(lua.CheckInteger(4)); + srcWidth = Nz::ranged_cast(lua.CheckInteger(4)); if (argCount >= 5) { - srcHeight = ranged_cast(lua.CheckInteger(5)); + srcHeight = Nz::ranged_cast(lua.CheckInteger(5)); if (argCount >= 6) - level = ranged_cast(lua.CheckInteger(6)); + level = Nz::ranged_cast(lua.CheckInteger(6)); } } } diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 0cb1f809d..1c6d6b9f2 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -15,6 +15,7 @@ #include #include #include +#include struct lua_Debug; struct lua_State; @@ -189,6 +190,14 @@ namespace Nz lua_State* m_state; unsigned int m_level; }; + + // Performs a 'ranged cast' to type T, i.e. a cast guaranteed to end up within the numerical limits of the type (or the limits provided in argument), + // without over- or under-flowing. + // Values beyond that range will be truncated to the type minimum (resp. maximum) if they are greater (resp. lesser) than the initial value. + template T ranged_cast(long long a, T high = std::numeric_limits::max(), T low = std::numeric_limits::min()) + { + return static_cast(std::min(static_cast(high), std::max(a, static_cast(low)))); + } } #include From d7ab29e5ef563239457bd4c5f7cfef033601557b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 24 Jan 2016 15:20:14 +0100 Subject: [PATCH 082/229] Fix and improve last PR Former-commit-id: 16afead68e42411402dfb5a7bd957a4940b6f83a --- .gitignore | 6 +- SDK/include/NDK/Application.hpp | 4 +- SDK/include/NDK/LuaAPI.hpp | 4 +- SDK/src/NDK/LuaAPI_Audio.cpp | 17 +- SDK/src/NDK/LuaAPI_Core.cpp | 256 ++---- SDK/src/NDK/LuaAPI_Graphics.cpp | 1 - SDK/src/NDK/LuaAPI_Math.cpp | 166 ++-- SDK/src/NDK/LuaAPI_Renderer.cpp | 133 --- SDK/src/NDK/LuaAPI_Utility.cpp | 83 ++ build/Build CodeBlocks (complete, united).bat | 2 +- build/scripts/common.lua | 14 +- build/scripts/common5.lua | 839 ------------------ include/Nazara/Lua/LuaInstance.hpp | 12 +- include/Nazara/Lua/LuaInstance.inl | 67 +- 14 files changed, 325 insertions(+), 1279 deletions(-) delete mode 100644 build/scripts/common5.lua diff --git a/.gitignore b/.gitignore index ba135329b..5fe1f32e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Nazara build examples/bin/*.exe +examples/bin/*.pdb tests/*.exe +tests/*.pdb lib/* # Feature page @@ -22,6 +24,7 @@ build/**/*.workspace build/**/*.project # Visual Studio +build/**/*.pdb build/**/*.filters build/**/*.vcxproj build/**/*.tlog @@ -30,7 +33,6 @@ build/**/*.vcxprojResolveAssemblyReference.cache build/**/*.nativecodeanalysis.all.xml build/**/*.nativecodeanalysis.xml build/**/*.VC.opendb -lib/*.exp # Compiled Object files build/**/*.slo @@ -40,7 +42,6 @@ build/**/*.obj # Compiled Dynamic libraries build/**/*.so -lib/*.lib # Compiled Static libraries build/**/*.lai @@ -75,7 +76,6 @@ $RECYCLE.BIN/ *.ilk *.meta *.pch -*.pdb *.pgc *.pgd *.rsp diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index b35c6c7f7..9b6eedae1 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -14,8 +14,8 @@ namespace Ndk class NDK_API Application { public: - Application(); - ~Application(); + inline Application(); + inline ~Application(); }; } diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index 8965229e2..fe8e343ce 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -24,10 +24,10 @@ namespace Ndk static void Register_Audio(Nz::LuaInstance& instance); static void Register_Core(Nz::LuaInstance& instance); - static void Register_Math(Nz::LuaInstance& instance); - static void Register_Utility(Nz::LuaInstance& instance); static void Register_Graphics(Nz::LuaInstance& instance); + static void Register_Math(Nz::LuaInstance& instance); static void Register_Renderer(Nz::LuaInstance& instance); + static void Register_Utility(Nz::LuaInstance& instance); }; } diff --git a/SDK/src/NDK/LuaAPI_Audio.cpp b/SDK/src/NDK/LuaAPI_Audio.cpp index c334b0454..abe5638d4 100644 --- a/SDK/src/NDK/LuaAPI_Audio.cpp +++ b/SDK/src/NDK/LuaAPI_Audio.cpp @@ -11,7 +11,8 @@ namespace Ndk /*********************************** Nz::SoundBuffer **********************************/ Nz::LuaClass soundBuffer("SoundBuffer"); - soundBuffer.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::SoundBufferRef* { + soundBuffer.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::SoundBufferRef* + { return new Nz::SoundBufferRef(new Nz::SoundBuffer); }); @@ -35,7 +36,7 @@ namespace Ndk std::size_t bufferSize = 0; const char* buffer = lua.CheckString(index, &bufferSize); - lua.ArgCheck(buffer && bufferSize < sampleCount * sizeof(Nz::Int16), index, "Invalid buffer"); + lua.ArgCheck(buffer && bufferSize >= sampleCount * sizeof(Nz::Int16), index, "Invalid buffer"); lua.PushBoolean(instance->Create(format, sampleCount, sampleRate, reinterpret_cast(buffer))); return 1; @@ -47,7 +48,8 @@ namespace Ndk return 1; }); - soundBuffer.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int { + soundBuffer.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int + { Nz::StringStream stream("SoundBuffer("); if (soundBuffer->IsValid()) { @@ -97,8 +99,8 @@ namespace Ndk Nz::LuaClass soundClass("Sound"); soundClass.Inherit(soundEmitter); - // Constructeur - soundClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Sound* { + soundClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Sound* + { return new Nz::Sound; }); @@ -108,8 +110,9 @@ namespace Ndk soundClass.SetMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); soundClass.SetMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); - // Nz::Sound::__tostring (Manual) - soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int { + // Manual + soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int + { Nz::StringStream stream("Sound("); if (const Nz::SoundBuffer* buffer = sound.GetBuffer()) stream << buffer; diff --git a/SDK/src/NDK/LuaAPI_Core.cpp b/SDK/src/NDK/LuaAPI_Core.cpp index 49cce49fd..7529e4eae 100644 --- a/SDK/src/NDK/LuaAPI_Core.cpp +++ b/SDK/src/NDK/LuaAPI_Core.cpp @@ -10,76 +10,13 @@ namespace Ndk { void LuaAPI::Register_Core(Nz::LuaInstance& instance) { - /******************************** Nz::AbstractHash *******************************/ - Nz::LuaClass abstractHashClass("AbstractHash"); - - abstractHashClass.SetMethod("__tostring", - [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int - { - Nz::StringStream strStrm("Nz::AbstractHash("); - - strStrm << "Hash type: " << hash.GetHashName() << ", "; - strStrm << "Digest size: " << hash.GetDigestLength() << ")"; - - lua.PushString(strStrm); - return 1; - }); - - abstractHashClass.SetMethod("Append", - [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int - { - size_t dataLength = 0; - const Nz::UInt8* data = reinterpret_cast(lua.CheckString(1, &dataLength)); - - hash.Append(data, dataLength); - - return 0; - }); - - abstractHashClass.SetMethod("Begin", &Nz::AbstractHash::Begin); - - abstractHashClass.SetMethod("End", - [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int - { - Nz::ByteArray data(hash.End()); - - lua.PushString(data.ToString()); - return 1; - }); - - abstractHashClass.SetMethod("GetDigestLength", &Nz::AbstractHash::GetDigestLength); - - abstractHashClass.SetMethod("GetHashName", - [](Nz::LuaInstance& lua, Nz::AbstractHash& hash) -> int - { - Nz::String hashName(hash.GetHashName()); - lua.PushString(hashName); - return 1; - }); - - abstractHashClass.Register(instance); - - /********************************** Nz::HashMD5 **********************************/ - Nz::LuaClass hashMD5Class("HashMD5"); - hashMD5Class.Inherit(abstractHashClass); - - hashMD5Class.SetConstructor( - [](Nz::LuaInstance& lua) -> Nz::HashMD5* - { - if(std::min(lua.GetStackTop(), 1U) == 0) - return new Nz::HashMD5(); - return nullptr; - }); - - hashMD5Class.Register(instance); - /*********************************** Nz::Clock **********************************/ Nz::LuaClass clockClass("Clock"); - // Constructeur - clockClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Clock* { - int index = 1; - return new Nz::Clock(lua.Check(&index, 0), lua.Check(&index, false)); + clockClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Clock* + { + int argIndex = 1; + return new Nz::Clock(lua.Check(&argIndex, 0), lua.Check(&argIndex, false)); }); clockClass.SetMethod("GetMicroseconds", &Nz::Clock::GetMicroseconds); @@ -90,7 +27,7 @@ namespace Ndk clockClass.SetMethod("Restart", &Nz::Clock::Restart); clockClass.SetMethod("Unpause", &Nz::Clock::Unpause); - // Nz::Clock::__tostring (Manual) + // Manual clockClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& clock) -> int { Nz::StringStream stream("Clock(Elapsed: "); stream << clock.GetSeconds(); @@ -108,21 +45,18 @@ namespace Ndk /********************************* Nz::Directory ********************************/ Nz::LuaClass directoryClass("Directory"); - // Constructeur - directoryClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Directory* { + directoryClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Directory* + { unsigned int argCount = std::min(lua.GetStackTop(), 1U); + + int argIndex = 1; switch (argCount) { case 0: - { return new Nz::Directory; - } case 1: - { - int index = 1; - return new Nz::Directory(lua.Check(&index)); - } + return new Nz::Directory(lua.Check(&argIndex)); } return nullptr; @@ -149,7 +83,7 @@ namespace Ndk directoryClass.SetStaticMethod("Remove", Nz::Directory::Remove); directoryClass.SetStaticMethod("SetCurrent", Nz::Directory::SetCurrent); - // Nz::Directory::__tostring (Manual) + // Manual directoryClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Directory& directory) -> int { Nz::StringStream stream("Directory("); stream << directory.GetPath(); @@ -181,8 +115,9 @@ namespace Ndk streamClass.SetMethod("SetCursorPos", &Nz::Stream::SetCursorPos); streamClass.SetMethod("Read", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { - int length = lua.CheckInteger(1); - lua.ArgCheck(length > 0, 1, "length must be positive"); + int argIndex = 1; + + std::size_t length = lua.Check(&argIndex); std::unique_ptr buffer(new char[length]); std::size_t readLength = stream.Read(buffer.get(), length); @@ -192,10 +127,10 @@ namespace Ndk }); streamClass.SetMethod("Write", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { - int index = 1; + int argIndex = 1; std::size_t bufferSize = 0; - const char* buffer = lua.CheckString(index, &bufferSize); + const char* buffer = lua.CheckString(argIndex, &bufferSize); if (stream.IsTextModeEnabled()) lua.Push(stream.Write(Nz::String(buffer, bufferSize))); @@ -210,30 +145,21 @@ namespace Ndk Nz::LuaClass fileClass("File"); fileClass.Inherit(streamClass); - // Constructeur - fileClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::File* { + fileClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::File* + { unsigned int argCount = std::min(lua.GetStackTop(), 2U); + + int argIndex = 1; switch (argCount) { case 0: - { return new Nz::File; - } case 1: - { - Nz::String filePath(lua.CheckString(1)); - - return new Nz::File(filePath); - } + return new Nz::File(lua.Check(&argIndex)); case 2: - { - Nz::String filePath(lua.CheckString(1)); - unsigned long openMode(lua.CheckInteger(2)); - - return new Nz::File(filePath, openMode); - } + return new Nz::File(lua.Check(&argIndex), lua.Check(&argIndex)); } return nullptr; @@ -253,80 +179,53 @@ namespace Ndk fileClass.SetMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); fileClass.SetMethod("SetFile", &Nz::File::GetLastWriteTime); - fileClass.SetMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + fileClass.SetStaticMethod("AbsolutePath", &Nz::File::AbsolutePath); + fileClass.SetStaticMethod("ComputeHash", (Nz::ByteArray (*)(Nz::HashType, const Nz::String&)) &Nz::File::ComputeHash); + fileClass.SetStaticMethod("Copy", &Nz::File::Copy); + fileClass.SetStaticMethod("Delete", &Nz::File::Delete); + fileClass.SetStaticMethod("Exists", &Nz::File::Exists); + //fileClass.SetStaticMethod("GetCreationTime", &Nz::File::GetCreationTime); + fileClass.SetStaticMethod("GetDirectory", &Nz::File::GetDirectory); + //fileClass.SetStaticMethod("GetLastAccessTime", &Nz::File::GetLastAccessTime); + //fileClass.SetStaticMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); + fileClass.SetStaticMethod("GetSize", &Nz::File::GetSize); + fileClass.SetStaticMethod("IsAbsolute", &Nz::File::IsAbsolute); + fileClass.SetStaticMethod("NormalizePath", &Nz::File::NormalizePath); + fileClass.SetStaticMethod("NormalizeSeparators", &Nz::File::NormalizeSeparators); + fileClass.SetStaticMethod("Rename", &Nz::File::Rename); + + // Manual + fileClass.SetMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& file) -> int + { unsigned int argCount = std::min(lua.GetStackTop(), 2U); + + int argIndex = 1; switch (argCount) { case 0: - { - bool _ret = file.Open(); - - lua.PushBoolean(_ret); - return 1; - } - case 1: - { - if (lua.IsOfType(1, Nz::LuaType_Number)) - { - unsigned long openMode(lua.ToInteger(1)); - - bool _ret = file.Open(openMode); - - lua.PushBoolean(_ret); - return 1; - } - else if (lua.IsOfType(1, Nz::LuaType_String)) - { - Nz::String filePath(lua.ToString(1)); - - bool _ret = file.Open(filePath); - - lua.PushBoolean(_ret); - return 1; - } - } + return lua.Push(file.Open(lua.Check(&argIndex, Nz::OpenMode_NotOpen))); case 2: - { - Nz::String filePath(lua.CheckString(1)); - unsigned long openMode(lua.CheckInteger(2)); - - bool _ret = file.Open(filePath, openMode); - - lua.PushBoolean(_ret); - return 1; - } + return lua.Push(file.Open(lua.Check(&argIndex), lua.Check(&argIndex, Nz::OpenMode_NotOpen))); } lua.Error("No matching overload for method Open"); return 0; }); - fileClass.SetMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + fileClass.SetMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& file) -> int + { unsigned int argCount = std::min(lua.GetStackTop(), 2U); + + int argIndex = 1; switch (argCount) { case 1: - { - Nz::UInt64 offset(lua.CheckInteger(1)); - - bool _ret = file.SetCursorPos(offset); - - lua.PushBoolean(_ret); - return 1; - } + return lua.Push(file.SetCursorPos(lua.Check(&argIndex))); case 2: - { - Nz::CursorPosition pos(static_cast(lua.CheckInteger(1))); - Nz::Int64 offset(lua.CheckInteger(2)); - - bool _ret = file.SetCursorPos(pos, offset); - - lua.PushBoolean(_ret); - return 1; - } + return lua.Push(file.SetCursorPos(lua.Check(&argIndex), lua.Check(&argIndex))); } lua.Error("No matching overload for method SetCursorPos"); @@ -346,24 +245,47 @@ namespace Ndk fileClass.Register(instance); - // Énumérations de la classe Nz::File - fileClass.PushGlobalTable(instance); + // Enums - // Nz::File::CursorPosition - instance.SetField("AtBegin", Nz::CursorPosition_AtBegin); - instance.SetField("AtCurrent", Nz::CursorPosition_AtCurrent); - instance.SetField("AtEnd", Nz::CursorPosition_AtEnd); + // Nz::CursorPosition + static_assert(Nz::CursorPosition_Max + 1 == 3, "Nz::CursorPosition has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 3); + { + instance.SetField("AtBegin", Nz::CursorPosition_AtBegin); + instance.SetField("AtCurrent", Nz::CursorPosition_AtCurrent); + instance.SetField("AtEnd", Nz::CursorPosition_AtEnd); + } + instance.SetGlobal("CursorPosition"); - // Nz::File::OpenMode - instance.SetField("Append", Nz::OpenMode_Append); - instance.SetField("NotOpen", Nz::OpenMode_NotOpen); - instance.SetField("Lock", Nz::OpenMode_Lock); - instance.SetField("ReadOnly", Nz::OpenMode_ReadOnly); - instance.SetField("ReadWrite", Nz::OpenMode_ReadWrite); - instance.SetField("Text", Nz::OpenMode_Text); - instance.SetField("Truncate", Nz::OpenMode_Truncate); - instance.SetField("WriteOnly", Nz::OpenMode_WriteOnly); + // Nz::HashType + static_assert(Nz::HashType_Max + 1 == 9, "Nz::HashType has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 9); + { + instance.SetField("CRC32", Nz::HashType_CRC32); + instance.SetField("Fletcher16", Nz::HashType_Fletcher16); + instance.SetField("MD5", Nz::HashType_MD5); + instance.SetField("SHA1", Nz::HashType_SHA1); + instance.SetField("SHA224", Nz::HashType_SHA224); + instance.SetField("SHA256", Nz::HashType_SHA256); + instance.SetField("SHA384", Nz::HashType_SHA384); + instance.SetField("SHA512", Nz::HashType_SHA512); + instance.SetField("Whirlpool", Nz::HashType_Whirlpool); + } + instance.SetGlobal("HashType"); - instance.Pop(); + // Nz::OpenMode + static_assert(Nz::OpenMode_Max + 1 == 2 * (64), "Nz::OpenModeFlags has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 8); + { + instance.SetField("Append", Nz::OpenMode_Append); + instance.SetField("NotOpen", Nz::OpenMode_NotOpen); + instance.SetField("Lock", Nz::OpenMode_Lock); + instance.SetField("ReadOnly", Nz::OpenMode_ReadOnly); + instance.SetField("ReadWrite", Nz::OpenMode_ReadWrite); + instance.SetField("Text", Nz::OpenMode_Text); + instance.SetField("Truncate", Nz::OpenMode_Truncate); + instance.SetField("WriteOnly", Nz::OpenMode_WriteOnly); + } + instance.SetGlobal("OpenMode"); } } diff --git a/SDK/src/NDK/LuaAPI_Graphics.cpp b/SDK/src/NDK/LuaAPI_Graphics.cpp index 685e64cb5..08b68e853 100644 --- a/SDK/src/NDK/LuaAPI_Graphics.cpp +++ b/SDK/src/NDK/LuaAPI_Graphics.cpp @@ -10,6 +10,5 @@ namespace Ndk { void LuaAPI::Register_Graphics(Nz::LuaInstance& instance) { - } } \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_Math.cpp b/SDK/src/NDK/LuaAPI_Math.cpp index 053ff6f10..399610ee7 100644 --- a/SDK/src/NDK/LuaAPI_Math.cpp +++ b/SDK/src/NDK/LuaAPI_Math.cpp @@ -11,115 +11,113 @@ namespace Ndk /*********************************** Nz::Vector2 **********************************/ Nz::LuaClass vector2dClass("Vector2"); - vector2dClass.SetConstructor( - [](Nz::LuaInstance& lua) -> Nz::Vector2d* + vector2dClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Vector2d* + { + unsigned int argCount = std::min(lua.GetStackTop(), 2U); + switch (argCount) { - unsigned int argCount = std::min(lua.GetStackTop(), 2U); - switch (argCount) + case 0: + case 2: + return new Nz::Vector2d(lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0)); + + case 1: { - case 0: - case 2: - return new Nz::Vector2d(lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0)); + if (lua.IsOfType(1, Nz::LuaType_Number)) + return new Nz::Vector2d(lua.CheckNumber(1)); + else if (lua.IsOfType(1, "Vector2")) + return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); - case 1: - { - if (lua.IsOfType(1, Nz::LuaType_Number)) - return new Nz::Vector2d(lua.CheckNumber(1)); - else if (lua.IsOfType(1, "Vector2")) - return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); - - break; - } + break; } + } - lua.Error("No matching overload for Vector2 constructor"); - return nullptr; - }); + lua.Error("No matching overload for Vector2 constructor"); + return nullptr; + }); vector2dClass.SetMethod("__tostring", &Nz::Vector2d::ToString); - vector2dClass.SetGetter( - [](Nz::LuaInstance& lua, Nz::Vector2d& instance) + vector2dClass.SetGetter([](Nz::LuaInstance& lua, Nz::Vector2d& instance) + { + switch (lua.GetType(1)) { - switch (lua.GetType(1)) + case Nz::LuaType_Number: + lua.Push(instance[lua.CheckInteger(1)]); + return true; + + case Nz::LuaType_String: { - case Nz::LuaType_Number: - lua.Push(instance[lua.CheckInteger(1)]); - return true; + std::size_t length; + const char* xy = lua.CheckString(1, &length); - case Nz::LuaType_String: - { - std::size_t length; - const char* xy = lua.CheckString(1, &length); - - if (length != 1) - break; - - switch (xy[0]) - { - case 'x': - lua.Push(instance.x); - return true; - - case 'y': - lua.Push(instance.y); - return true; - } + if (length != 1) break; + + switch (xy[0]) + { + case 'x': + lua.Push(instance.x); + return true; + + case 'y': + lua.Push(instance.y); + return true; } + break; + } + } + + return false; + }); + + vector2dClass.SetSetter([](Nz::LuaInstance& lua, Nz::Vector2d& instance) + { + switch (lua.GetType(1)) + { + case Nz::LuaType_Number: + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 2) + return false; + + instance[index] = lua.CheckNumber(2); + return true; } - return false; - }); - - vector2dClass.SetSetter( - [](Nz::LuaInstance& lua, Nz::Vector2d& instance) - { - switch (lua.GetType(1)) + case Nz::LuaType_String: { - case Nz::LuaType_Number: - { - long long index = lua.CheckInteger(1); - if (index < 1 || index > 2) - return false; + std::size_t length; + const char* xy = lua.CheckString(1, &length); - instance[index] = lua.CheckNumber(2); - return true; - } - - case Nz::LuaType_String: - { - std::size_t length; - const char* xy = lua.CheckString(1, &length); - - if (length != 1) - break; - - double value = lua.CheckNumber(2); - - switch (xy[0]) - { - case 'x': - instance.x = value; - return true; - - case 'y': - instance.y = value; - return true; - } + if (length != 1) break; - } - } - return false; - }); + double value = lua.CheckNumber(2); + + switch (xy[0]) + { + case 'x': + instance.x = value; + return true; + + case 'y': + instance.y = value; + return true; + } + break; + } + } + + return false; + }); vector2dClass.Register(instance); /*********************************** Nz::Vector3 **********************************/ Nz::LuaClass vector3dClass("Vector3"); - vector3dClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Vector3d* { + vector3dClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Vector3d* + { unsigned int argCount = std::min(lua.GetStackTop(), 3U); switch (argCount) { diff --git a/SDK/src/NDK/LuaAPI_Renderer.cpp b/SDK/src/NDK/LuaAPI_Renderer.cpp index 5c801748a..cbbd24b92 100644 --- a/SDK/src/NDK/LuaAPI_Renderer.cpp +++ b/SDK/src/NDK/LuaAPI_Renderer.cpp @@ -11,138 +11,5 @@ namespace Ndk { void LuaAPI::Register_Renderer(Nz::LuaInstance& instance) { - /*********************************** Nz::AbstractImage **********************************/ - Nz::LuaClass abstractImage("AbstractImage"); - - abstractImage.SetMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); - abstractImage.SetMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); - abstractImage.SetMethod("GetFormat", &Nz::AbstractImage::GetFormat); - abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); - abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); - abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); - abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); - abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); - abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); - abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); - abstractImage.SetMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); - - abstractImage.SetMethod("GetMemoryUsage", - [](Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int - { - unsigned int memory = 0; - - unsigned int argCount = std::min(lua.GetStackTop(), 2U); - if (argCount == 1 && lua.IsOfType(1, Nz::LuaType_Number)) - memory = abstractImage->GetMemoryUsage(Nz::ranged_cast(lua.CheckInteger(1))); - else - memory = abstractImage->GetMemoryUsage(); - - lua.PushInteger(memory); - return 1; - }); - - abstractImage.SetMethod("__tostring", - [](Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int - { - lua.PushString(Nz::StringStream("AbstractImage()")); - return 1; - }); - - abstractImage.SetMethod("Update", - [](Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int - { - unsigned int argCount = std::min(lua.GetStackTop(), 2U); - - if (argCount < 1) - { - lua.Error("No matching overload for method AbstractImage::Update"); - return 0; - } - - bool rValue; - const Nz::UInt8* pixels = reinterpret_cast(lua.CheckString(1)); - - if (argCount == 1) - rValue = abstractImage->Update(pixels); - else - { - // Three possible overloads, based on second argument type - if (lua.IsOfType(2, Nz::LuaType_Number)) // Overload #1 - { - /* Prototype is: - virtual bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) - */ - - unsigned int srcWidth = Nz::ranged_cast(lua.CheckInteger(2)); - unsigned int srcHeight = 0; - Nz::UInt8 level = 0; - - if (argCount >= 3) - { - srcHeight = Nz::ranged_cast(lua.CheckInteger(3)); - if (argCount >= 4) - level = Nz::ranged_cast(lua.CheckInteger(3)); - } - - rValue = abstractImage->Update(pixels, srcWidth, srcHeight, level); - } - else if (lua.IsOfType(2, "Box")) // Overload #2 - { - /* Prototype is: - virtual bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) - */ - - Nz::Boxui box (*(static_cast(lua.ToUserdata(2)))); // Placeholder. Ask Lynix about templates & bindings. Nz::Box has to be bound, too. - unsigned int srcWidth = 0; - unsigned int srcHeight = 0; - Nz::UInt8 level = 0; - - if (argCount >= 3) - { - srcWidth = Nz::ranged_cast(lua.CheckInteger(3)); - if (argCount >= 4) - { - srcHeight = Nz::ranged_cast(lua.CheckInteger(4)); - if (argCount >= 5) - level = Nz::ranged_cast(lua.CheckInteger(5)); - } - } - rValue = abstractImage->Update(pixels, box, srcWidth, srcHeight, level); - } - else if (lua.IsOfType(2, "Rect")) // Overload #3 - { - /* Prototype is: - virtual bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) - */ - - Nz::Rectui rect(*(static_cast(lua.ToUserdata(2)))); // Placeholder. See comment at box declaration in overload #2 - unsigned int z = 0; - unsigned int srcWidth = 0; - unsigned int srcHeight = 0; - Nz::UInt8 level = 0; - - if (argCount >= 3) - { - z = Nz::ranged_cast(lua.CheckInteger(3)); - if (argCount >= 4) - { - srcWidth = Nz::ranged_cast(lua.CheckInteger(4)); - if (argCount >= 5) - { - srcHeight = Nz::ranged_cast(lua.CheckInteger(5)); - if (argCount >= 6) - level = Nz::ranged_cast(lua.CheckInteger(6)); - } - } - } - rValue = abstractImage->Update(pixels, rect, z, srcWidth, srcHeight, level); - } - } - - lua.PushBoolean(rValue); - return 1; - }); - - abstractImage.Register(instance); } } \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_Utility.cpp b/SDK/src/NDK/LuaAPI_Utility.cpp index 0f6bfb1cd..0f2659e1e 100644 --- a/SDK/src/NDK/LuaAPI_Utility.cpp +++ b/SDK/src/NDK/LuaAPI_Utility.cpp @@ -10,5 +10,88 @@ namespace Ndk { void LuaAPI::Register_Utility(Nz::LuaInstance& instance) { + /*********************************** Nz::AbstractImage **********************************/ + Nz::LuaClass abstractImage("AbstractImage"); + + abstractImage.SetMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); + abstractImage.SetMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); + abstractImage.SetMethod("GetFormat", &Nz::AbstractImage::GetFormat); + abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); + abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); + abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); + abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); + abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); + abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); + abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); + abstractImage.SetMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); + + abstractImage.SetMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 1U); + switch (argCount) + { + case 0: + return lua.Push(abstractImage->GetMemoryUsage()); + + case 1: + { + int index = 1; + Nz::UInt8 level(lua.Check(&index)); + + return lua.Push(abstractImage->GetMemoryUsage(level)); + } + } + + lua.Error("No matching overload for method GetMemoryUsage"); + return 0; + }); + + abstractImage.SetMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 6U); + int argIndex = 1; + + std::size_t bufferSize = 0; + const Nz::UInt8* pixels = reinterpret_cast(lua.CheckString(argIndex++, &bufferSize)); + + if (argCount < 2 || lua.IsOfType(2, Nz::LuaType_Number)) + { + // bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + unsigned int srcWidth = lua.Check(&argIndex, 0); + unsigned int srcHeight = lua.Check(&argIndex, 0); + Nz::UInt8 level = lua.Check(&argIndex, 0); + + ///TODO: Buffer checks (Nz::ByteBufferView ?) + return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); + } + /* Disabled until Box and Rect have been ported + else if (lua.IsOfType(2, "Box")) + { + // bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + Nz::Boxui box = lua.Check(&argIndex); + unsigned int srcWidth = lua.Check(&argIndex, 0); + unsigned int srcHeight = lua.Check(&argIndex, 0); + Nz::UInt8 level = lua.Check(&argIndex, 0); + + ///TODO: Buffer checks (Nz::ByteBufferView ?) + return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); + } + else if (lua.IsOfType(2, "Rect")) + { + // bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + Nz::Rectui box = lua.Check(&argIndex); + unsigned int srcWidth = lua.Check(&argIndex, 0); + unsigned int srcHeight = lua.Check(&argIndex, 0); + Nz::UInt8 level = lua.Check(&argIndex, 0); + + ///TODO: Buffer checks (Nz::ByteBufferView ?) + return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); + }*/ + + lua.Error("No matching overload for method Update"); + return 0; + }); + + abstractImage.Register(instance); } } \ No newline at end of file diff --git a/build/Build CodeBlocks (complete, united).bat b/build/Build CodeBlocks (complete, united).bat index 28aaad58f..b7c5ab4c9 100644 --- a/build/Build CodeBlocks (complete, united).bat +++ b/build/Build CodeBlocks (complete, united).bat @@ -1 +1 @@ -premake5 --united --with-extlibs --with-examples codeblocks \ No newline at end of file +premake4 --united --with-extlibs --with-examples codeblocks \ No newline at end of file diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 90afe4217..1018890b8 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -9,7 +9,7 @@ function NazaraBuild:Execute() local makeLibDir = os.is("windows") and "mingw" or "gmake" if (#self.OrderedExtLibs > 0) then - solution("NazaraExtlibs") + workspace("NazaraExtlibs") platforms({"x32", "x64"}) -- Configuration générale @@ -60,7 +60,10 @@ function NazaraBuild:Execute() flags("Symbols") configuration("Release*") - flags({"EnableSSE2", "Optimize", "OptimizeSpeed", "NoFramePointer", "NoRTTI"}) + flags("NoFramePointer") + optimize("Speed") + rtti("Off") + vectorextensions("SSE2") configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants @@ -98,7 +101,7 @@ function NazaraBuild:Execute() end end - solution("NazaraEngine") + workspace("NazaraEngine") platforms({"x32", "x64"}) -- Configuration générale @@ -117,7 +120,10 @@ function NazaraBuild:Execute() flags("Symbols") configuration("Release*") - flags({"EnableSSE2", "Optimize", "OptimizeSpeed", "NoFramePointer", "NoRTTI"}) + flags("NoFramePointer") + optimize("Speed") + rtti("Off") + vectorextensions("SSE2") configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants diff --git a/build/scripts/common5.lua b/build/scripts/common5.lua deleted file mode 100644 index b32205e27..000000000 --- a/build/scripts/common5.lua +++ /dev/null @@ -1,839 +0,0 @@ -NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table - -function NazaraBuild:Execute() - 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 - end - - if (self.Actions[_ACTION] == nil) then - local makeLibDir = os.is("windows") and "mingw" or "gmake" - - if (#self.OrderedExtLibs > 0) then - solution("NazaraExtlibs") - platforms({"x32", "x64"}) - - -- Configuration générale - configurations({ - "DebugStatic", - "ReleaseStatic" - }) - - includedirs("../extlibs/include") - libdirs("../extlibs/lib/common") - location(_ACTION) - kind("StaticLib") - - configuration("x32") - libdirs("../extlibs/lib/common/x86") - - configuration("x64") - libdirs("../extlibs/lib/common/x64") - - configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") - targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") - - configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") - targetdir("../extlibs/lib/" .. makeLibDir .. "/x64") - - configuration("vs*") - buildoptions("/MP") - - configuration({"vs*", "x32"}) - libdirs("../extlibs/lib/msvc/x86") - targetdir("../extlibs/lib/msvc/x86") - - configuration({"vs*", "x64"}) - libdirs("../extlibs/lib/msvc/x64") - targetdir("../extlibs/lib/msvc/x64") - - configuration({"xcode3 or xcode4", "x32"}) - libdirs("../extlibs/lib/xcode/x86") - targetdir("../extlibs/lib/xcode/x86") - - configuration({"xcode3 or xcode4", "x64"}) - libdirs("../extlibs/lib/xcode/x64") - targetdir("../extlibs/lib/xcode/x64") - - configuration("Debug*") - flags("Symbols") - - configuration("Release*") - flags({"EnableSSE2", "Optimize", "OptimizeSpeed", "NoFramePointer"}) - rtti("Off") - - configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) - buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants - buildoptions("-ftree-vectorize") -- Activation de la vectorisation du code - - configuration("DebugStatic") - targetsuffix("-s-d") - - configuration("ReleaseStatic") - targetsuffix("-s") - - configuration("codeblocks or codelite or gmake or xcode3 or xcode4") - buildoptions({"-fPIC", "-std=c++14"}) - - for k, libTable in ipairs(self.OrderedExtLibs) do - project(libTable.Name) - - language(libTable.Language) - location(_ACTION .. "/extlibs") - - files(libTable.Files) - excludes(libTable.FilesExclusion) - - defines(libTable.Defines) - flags(libTable.Flags) - includedirs(libTable.Includes) - links(libTable.Libraries) - - for k,v in pairs(libTable.ConfigurationLibraries) do - configuration(k) - links(v) - end - - configuration({}) - end - end - - solution("NazaraEngine") - platforms({"x32", "x64"}) - - -- Configuration générale - configurations({ - -- "DebugStatic", - -- "ReleaseStatic", - "DebugDynamic", - "ReleaseDynamic" - }) - - language("C++") - location(_ACTION) - - configuration("Debug*") - defines("NAZARA_DEBUG") - flags("Symbols") - - configuration("Release*") - flags({"EnableSSE2", "Optimize", "OptimizeSpeed", "NoFramePointer"}) - rtti("Off") - - configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) - buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants - buildoptions("-ftree-vectorize") -- Activation de la vectorisation du code - - configuration("*Static") - defines("NAZARA_STATIC") - - configuration("codeblocks or codelite or gmake or xcode3 or xcode4") - buildoptions("-std=c++14") - - configuration({"linux or bsd or macosx", "gmake"}) - buildoptions("-fvisibility=hidden") - - configuration({"linux or bsd or macosx", "gmake"}) - buildoptions("-fvisibility=hidden") - - configuration("vs*") - buildoptions("/MP") -- Multiprocessus build - flags("NoMinimalRebuild") - defines("_CRT_SECURE_NO_WARNINGS") - defines("_SCL_SECURE_NO_WARNINGS") - - - -- Spécification des modules - if (_OPTIONS["united"]) then - project("NazaraEngine") - end - - for k, moduleTable in ipairs(self.OrderedModules) do - if (not _OPTIONS["united"]) then - project("Nazara" .. moduleTable.Name) - end - - location(_ACTION .. "/modules") - - defines("NAZARA_BUILD") - - includedirs({ - "../include", - "../src/", - "../extlibs/include" - }) - - libdirs("../lib") - libdirs("../extlibs/lib/common") - - configuration("x32") - libdirs("../extlibs/lib/common/x86") - - configuration("x64") - defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") - - configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") - libdirs("../lib/" .. makeLibDir .. "/x86") - targetdir("../lib/" .. makeLibDir .. "/x86") - - configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") - libdirs("../lib/" .. makeLibDir .. "/x64") - targetdir("../lib/" .. makeLibDir .. "/x64") - - configuration({"vs*", "x32"}) - libdirs("../extlibs/lib/msvc/x86") - libdirs("../lib/msvc/x86") - targetdir("../lib/msvc/x86") - - configuration({"vs*", "x64"}) - libdirs("../extlibs/lib/msvc/x64") - libdirs("../lib/msvc/x64") - targetdir("../lib/msvc/x64") - - configuration({"xcode3 or xcode4", "x32"}) - libdirs("../extlibs/lib/xcode/x86") - libdirs("../lib/xcode/x86") - targetdir("../lib/xcode/x86") - - configuration({"xcode3 or xcode4", "x64"}) - libdirs("../extlibs/lib/xcode/x64") - libdirs("../lib/xcode/x64") - targetdir("../lib/xcode/x64") - - configuration("*Static") - kind("StaticLib") - - configuration("*Dynamic") - kind("SharedLib") - - configuration("DebugStatic") - targetsuffix("-s-d") - - configuration("ReleaseStatic") - targetsuffix("-s") - - configuration("DebugDynamic") - targetsuffix("-d") - - configuration({}) - - files(moduleTable.Files) - excludes(moduleTable.FilesExclusion) - - defines(moduleTable.Defines) - flags(moduleTable.Flags) - includedirs(moduleTable.Includes) - links(moduleTable.Libraries) - - for k,v in pairs(moduleTable.ConfigurationLibraries) do - configuration(k) - links(v) - end - - configuration({}) - end - - -- Tools - for k, toolTable in ipairs(self.OrderedTools) do - project("Nazara" .. toolTable.Name) - - location(_ACTION .. "/tools") - targetdir(toolTable.Directory) - - if (toolTable.Kind == "library") then - kind("SharedLib") - elseif (toolTable.Kind == "consoleapp") then - debugdir(toolTable.Directory) - kind("ConsoleApp") - elseif (toolTable.Kind == "windowapp") then - debugdir(toolTable.Directory) - kind("WindowedApp") - else - assert(false, "wut") - end - - includedirs({ - "../include", - "../extlibs/include" - }) - - libdirs("../lib") - libdirs("../extlibs/lib/common") - - configuration("x32") - libdirs("../extlibs/lib/common/x86") - - configuration("x64") - defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") - - configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") - libdirs("../lib/" .. makeLibDir .. "/x86") - if (toolTable.Kind == "library") then - targetdir("../lib/" .. makeLibDir .. "/x86") - end - - configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") - libdirs("../lib/" .. makeLibDir .. "/x64") - if (toolTable.Kind == "library") then - targetdir("../lib/" .. makeLibDir .. "/x64") - end - - configuration({"vs*", "x32"}) - libdirs("../extlibs/lib/msvc/x86") - libdirs("../lib/msvc/x86") - if (toolTable.Kind == "library") then - targetdir("../lib/msvc/x86") - end - - configuration({"vs*", "x64"}) - libdirs("../extlibs/lib/msvc/x64") - libdirs("../lib/msvc/x64") - if (toolTable.Kind == "library") then - targetdir("../lib/msvc/x64") - end - - configuration({"xcode3 or xcode4", "x32"}) - libdirs("../extlibs/lib/xcode/x86") - libdirs("../lib/xcode/x86") - if (toolTable.Kind == "library") then - targetdir("../lib/xcode/x86") - end - - configuration({"xcode3 or xcode4", "x64"}) - libdirs("../extlibs/lib/xcode/x64") - libdirs("../lib/xcode/x64") - if (toolTable.Kind == "library") then - targetdir("../lib/xcode/x64") - end - - if (toolTable.Kind == "library") then - configuration("*Static") - kind("StaticLib") - - configuration("*Dynamic") - kind("SharedLib") - - configuration("DebugStatic") - targetsuffix("-s-d") - - configuration("ReleaseStatic") - targetsuffix("-s") - - configuration("DebugDynamic") - targetsuffix("-d") - end - - configuration({}) - - files(toolTable.Files) - excludes(toolTable.FilesExclusion) - - defines(toolTable.Defines) - flags(toolTable.Flags) - includedirs(toolTable.Includes) - links(toolTable.Libraries) - - for k,v in pairs(toolTable.ConfigurationLibraries) do - configuration(k) - links(v) - end - - configuration({}) - end - - for k, exampleTable in ipairs(self.OrderedExamples) do - project("Demo" .. exampleTable.Name) - - location(_ACTION .. "/examples") - - if (exampleTable.Console) then - kind("ConsoleApp") - else - kind("Window") - end - - debugdir("../examples/bin") - includedirs({ - "../include", - "../extlibs/include" - }) - libdirs("../lib") - targetdir("../examples/bin") - - files(exampleTable.Files) - excludes(exampleTable.FilesExclusion) - - defines(exampleTable.Defines) - flags(exampleTable.Flags) - includedirs(exampleTable.Includes) - links(exampleTable.Libraries) - - configuration("x32") - libdirs("../extlibs/lib/common/x86") - - configuration("x64") - defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") - - configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../lib/" .. makeLibDir .. "/x86") - - configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../lib/" .. makeLibDir .. "/x64") - - configuration({"vs*", "x32"}) - libdirs("../lib/msvc/x86") - - configuration({"vs*", "x64"}) - libdirs("../lib/msvc/x64") - - configuration({"xcode3 or xcode4", "x32"}) - libdirs("../lib/xcode/x86") - - configuration({"xcode3 or xcode4", "x64"}) - libdirs("../lib/xcode/x64") - - for k,v in pairs(exampleTable.ConfigurationLibraries) do - configuration(k) - links(v) - end - - configuration({}) - end - end -end - -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.Examples = {} - self.ExtLibs = {} - self.Modules = {} - self.Tools = {} - - -- Actions - modules = os.matchfiles("scripts/actions/*.lua") - for k,v in pairs(modules) do - local f, err = loadfile(v) - if (f) then - ACTION = {} - - f() - - local succeed, err = self:RegisterAction(ACTION) - if (not succeed) then - print("Unable to register action: " .. err) - end - else - print("Unable to load action file: " .. err) - end - end - ACTION = nil - - -- Extern libraries - if (_OPTIONS["with-extlibs"]) then - local extlibs = os.matchfiles("../extlibs/build/*.lua") - for k,v in pairs(extlibs) do - local f, err = loadfile(v) - if (f) then - LIBRARY = {} - self:SetupInfoTable(LIBRARY) - - f() - - local succeed, err = self:RegisterExternLibrary(LIBRARY) - if (not succeed) then - print("Unable to register extern library: " .. err) - end - else - print("Unable to load extern library file: " .. err) - end - end - LIBRARY = nil - end - - -- Then the modules - local modules = os.matchfiles("scripts/modules/*.lua") - for k,v in pairs(modules) do - local moduleName = v:match(".*/(.*).lua") - 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) - if (f) then - MODULE = {} - self:SetupInfoTable(MODULE) - - f() - - local succeed, err = self:RegisterModule(MODULE) - if (not succeed) then - print("Unable to register module: " .. err) - end - else - print("Unable to load module file: " .. err) - end - end - end - MODULE = nil - - -- Continue with the tools (ex: SDK) - local tools = os.matchfiles("scripts/tools/*.lua") - for k,v in pairs(tools) do - local toolName = v:match(".*/(.*).lua") - 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) - if (f) then - TOOL = {} - self:SetupInfoTable(TOOL) - - f() - - local succeed, err = self:RegisterTool(TOOL) - if (not succeed) then - print("Unable to register tool: " .. err) - end - else - print("Unable to load tool file: " .. err) - end - end - end - TOOL = nil - - -- Examples - if (_OPTIONS["with-examples"]) then - local examples = os.matchdirs("../examples/*") - for k,v in pairs(examples) do - local dirName = v:match(".*/(.*)") - if (dirName ~= "bin" and dirName ~= "build") then - local f, err = loadfile(v .. "/build.lua") - if (f) then - EXAMPLE = {} - EXAMPLE.Directory = dirName - self:SetupInfoTable(EXAMPLE) - - f() - - local succeed, err = self:RegisterExample(EXAMPLE) - if (not succeed) then - print("Unable to register example: " .. err) - end - else - print("Unable to load example file: " .. err) - end - end - end - EXAMPLE = nil - end - - -- Once everything is registred, let's process all the tables - self.OrderedExamples = {} - self.OrderedExtLibs = {} - self.OrderedModules = {} - self.OrderedTools = {} - local tables = {self.Examples, self.ExtLibs, self.Modules, self.Tools} - local orderedTables = {self.OrderedExamples, self.OrderedExtLibs, self.OrderedModules, self.OrderedTools} - for k,projects in ipairs(tables) do - for projectId,projectTable in pairs(projects) do - self:Process(projectTable) - - table.insert(orderedTables[k], projectTable) - end - - table.sort(orderedTables[k], function (a, b) return a.Name < b.Name end) - end -end - -function NazaraBuild:RegisterAction(actionTable) - if (actionTable.Name == nil or type(actionTable.Name) ~= "string" or string.len(actionTable.Name) == 0) then - return false, "Invalid action name" - end - - local lowerCaseName = string.lower(actionTable.Name) - if (self.Actions[lowerCaseName] ~= nil) then - return false, "This action name is already in use" - end - - if (actionTable.Description == nil or type(actionTable.Description) ~= "string") then - return false, "Action description is invalid" - end - - if (string.len(actionTable.Description) == 0) then - return false, "Action description is empty" - end - - if (self.Actions[actionTable.name] ~= nil) then - return false, "Action name \"" .. actionTable.name .. " is already registred" - end - - if (actionTable.Function == nil or type(actionTable.Function) ~= "function") then - return false, "Action function is invalid" - end - - self.Actions[lowerCaseName] = actionTable - - newaction - { - trigger = lowerCaseName, - description = actionTable.Description, - execute = function () actionTable:Function() end - } - - return true -end - -function NazaraBuild:RegisterExample(exampleTable) - if (exampleTable.Name == nil or type(exampleTable.Name) ~= "string" or string.len(exampleTable.Name) == 0) then - return false, "Invalid example name" - end - - local lowerCaseName = exampleTable.Name:lower() - if (self.Examples[lowerCaseName] ~= nil) then - return false, "This library name is already in use" - end - - if (exampleTable.Files == nil or type(exampleTable.Files) ~= "table") then - return false, "Example files table is invalid" - end - - if (#exampleTable.Files == 0) then - return false, "This example has no files" - end - - local files = {} - for k, file in ipairs(exampleTable.Files) do - table.insert(files, "../examples/" .. exampleTable.Directory .. "/" .. file) - end - exampleTable.Files = files - - exampleTable.Type = "Example" - self.Examples[lowerCaseName] = exampleTable - return true -end - -function NazaraBuild:RegisterExternLibrary(libTable) - if (libTable.Name == nil or type(libTable.Name) ~= "string" or string.len(libTable.Name) == 0) then - return false, "Invalid library name" - end - - local lowerCaseName = libTable.Name:lower() - if (self.ExtLibs[lowerCaseName] ~= nil) then - return false, "This library name is already in use" - end - - if (libTable.Files == nil or type(libTable.Files) ~= "table") then - return false, "Invalid file table" - end - - if (#libTable.Files == 0) then - return false, "This library has no files" - end - - libTable.Type = "ExternLib" - self.ExtLibs[lowerCaseName] = libTable - return true -end - -function NazaraBuild:RegisterModule(moduleTable) - if (moduleTable.Name == nil or type(moduleTable.Name) ~= "string" or string.len(moduleTable.Name) == 0) then - return false, "Invalid module name" - end - - local lowerCaseName = moduleTable.Name:lower() - if (self.Modules[lowerCaseName] ~= nil) then - return false, "This module name is already in use" - end - - table.insert(moduleTable.Defines, "NAZARA_" .. moduleTable.Name:upper() .. "_BUILD") - table.insert(moduleTable.Files, "../include/Nazara/" .. moduleTable.Name .. "/**.hpp") - table.insert(moduleTable.Files, "../include/Nazara/" .. moduleTable.Name .. "/**.inl") - table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.hpp") - table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.inl") - table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.cpp") - - if (_OPTIONS["united"] and lowerCaseName ~= "core") then - table.insert(moduleTable.FilesExclusion, "../src/Nazara/" .. moduleTable.Name .. "/Debug/NewOverload.cpp") - end - - moduleTable.Type = "Module" - self.Modules[lowerCaseName] = moduleTable - return true -end - -function NazaraBuild:RegisterTool(toolTable) - if (toolTable.Name == nil or type(toolTable.Name) ~= "string" or string.len(toolTable.Name) == 0) then - return false, "Invalid tool name" - end - - local lowerCaseName = toolTable.Name:lower() - if (self.Tools[lowerCaseName] ~= nil) then - return false, "This tool name is already in use" - end - - if (toolTable.Directory == nil or type(toolTable.Directory) ~= "string" or string.len(toolTable.Directory) == 0) then - return false, "Invalid tool directory" - end - - if (toolTable.Kind == nil or type(toolTable.Kind) ~= "string" or string.len(toolTable.Kind) == 0) then - return false, "Invalid tool type" - end - - local lowerCaseKind = toolTable.Kind:lower() - if (lowerCaseKind == "library" or lowerCaseKind == "consoleapp" or lowerCaseKind == "windowapp") then - toolTable.Kind = lowerCaseKind - else - return false, "Invalid tool type" - end - - toolTable.Type = "Tool" - self.Tools[lowerCaseName] = toolTable - return true -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 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 - - if (not _OPTIONS["united"] 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 - else - local extLibTable = self.ExtLibs[library:lower()] - if (extLibTable) then - library = extLibTable.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") - 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 platform, fileTable in pairs(infoTable.OsFiles) 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(fileTable) do - table.insert(infoTable.Files, v) - end - else - for k,v in ipairs(fileTable) do - table.insert(infoTable.FilesExclusion, v) - end - end - end - infoTable.OsFiles = nil - - for platform, libraryTable in pairs(infoTable.OsLibraries) 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(libraryTable) do - table.insert(infoTable.Libraries, v) - end - end - end - infoTable.OsLibraries = nil -end - -function NazaraBuild:SetupInfoTable(infoTable) - infoTable.ConfigurationLibraries = {} - infoTable.ConfigurationLibraries.DebugStatic = {} - infoTable.ConfigurationLibraries.ReleaseStatic = {} - infoTable.ConfigurationLibraries.DebugDynamic = {} - infoTable.ConfigurationLibraries.ReleaseDynamic = {} - infoTable.Defines = {} - infoTable.Files = {} - infoTable.FilesExclusion = {} - infoTable.Flags = {} - infoTable.Includes = {} - infoTable.Libraries = {} - infoTable.OsFiles = {} - infoTable.OsLibraries = {} -end \ No newline at end of file diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 1c6d6b9f2..f60898e66 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -15,7 +15,6 @@ #include #include #include -#include struct lua_Debug; struct lua_State; @@ -48,6 +47,8 @@ namespace Nz void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; + template T CheckBoundInteger(int index) const; + template T CheckBoundInteger(int index, T defValue) const; template T CheckField(const char* fieldName, int tableIndex = -1) const; template T CheckField(const String& fieldName, int tableIndex = -1) const; template T CheckField(const char* fieldName, T defValue, int tableIndex = -1) const; @@ -176,6 +177,7 @@ namespace Nz static LuaInstance* GetInstance(lua_State* state); private: + template T CheckBounds(int index, long long value) const; bool Run(int argCount, int resultCount); static void* MemoryAllocator(void *ud, void *ptr, std::size_t osize, std::size_t nsize); @@ -190,14 +192,6 @@ namespace Nz lua_State* m_state; unsigned int m_level; }; - - // Performs a 'ranged cast' to type T, i.e. a cast guaranteed to end up within the numerical limits of the type (or the limits provided in argument), - // without over- or under-flowing. - // Values beyond that range will be truncated to the type minimum (resp. maximum) if they are greater (resp. lesser) than the initial value. - template T ranged_cast(long long a, T high = std::numeric_limits::max(), T low = std::numeric_limits::min()) - { - return static_cast(std::min(static_cast(high), std::max(a, static_cast(low)))); - } } #include diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 77155cba0..c7f72df34 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -3,8 +3,10 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include +#include "LuaInstance.hpp" namespace Nz { @@ -70,33 +72,19 @@ namespace Nz } template - std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) { - *arg = static_cast(instance.CheckInteger(index)); + *arg = instance.CheckBoundInteger(index); return 1; } template - std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { - *arg = static_cast(instance.CheckInteger(index, defValue)); + *arg = instance.CheckBoundInteger(index, defValue); return 1; } - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) - { - using SignedT = std::make_signed_t; - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - using SignedT = std::make_signed_t; - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); - } - template std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { @@ -148,26 +136,24 @@ namespace Nz } template - std::enable_if_t::value && !std::is_unsigned::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) + std::enable_if_t::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) { instance.PushInteger(val); return 1; } - template - std::enable_if_t::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - using SignedT = typename std::make_signed::type; - - return LuaImplReplyVal(instance, static_cast(val), TypeTag()); - } - inline int LuaImplReplyVal(const LuaInstance& instance, std::string val, TypeTag) { instance.PushString(val.c_str(), val.size()); return 1; } + inline int LuaImplReplyVal(const LuaInstance& instance, ByteArray val, TypeTag) + { + instance.PushString(reinterpret_cast(val.GetConstBuffer()), val.GetSize()); + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, String val, TypeTag) { instance.PushString(std::move(val)); @@ -420,6 +406,18 @@ namespace Nz return object; } + template + inline T LuaInstance::CheckBoundInteger(int index) const + { + return CheckBounds(index, CheckInteger(index)); + } + + template + inline T LuaInstance::CheckBoundInteger(int index, T defValue) const + { + return CheckBounds(index, CheckInteger(index, defValue)); + } + template T LuaInstance::CheckField(const char* fieldName, int tableIndex) const { @@ -550,4 +548,19 @@ namespace Nz { SetGlobal(name.GetConstBuffer(), std::forward(arg)); } + + template + T LuaInstance::CheckBounds(int index, long long value) const + { + long long minBounds = std::numeric_limits::min(); + long long maxBounds = std::numeric_limits::max(); + if (value < minBounds || value > maxBounds) + { + Nz::StringStream stream; + stream << "Argument #" << index << " is outside value range [" << minBounds << ", " << maxBounds << "] (" << value << ')'; + Error(stream); + } + + return static_cast(value); + } } From cbd73a9ac00f0d902a47859c214290833adc509d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 24 Jan 2016 15:22:53 +0100 Subject: [PATCH 084/229] Core/Enums: Fix OpenMode_Max Former-commit-id: eb356bf9d9469fdaff2b234aa7e61751644843a3 --- include/Nazara/Core/Enums.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 1fd884799..a261f2bd3 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -86,7 +86,7 @@ namespace Nz OpenMode_ReadWrite = OpenMode_ReadOnly | OpenMode_WriteOnly, // Ouvre en lecture/écriture - OpenMode_Max = OpenMode_WriteOnly + OpenMode_Max = OpenMode_WriteOnly*2 - 1 }; enum ParameterType @@ -177,7 +177,7 @@ namespace Nz StreamOption_Sequential = 0x1, StreamOption_Text = 0x2, - StreamOption_Max = StreamOption_Text*2-1 + StreamOption_Max = StreamOption_Text*2 - 1 }; enum Ternary From ed62fa5398d44147b7914812ef2a83bcff624cc2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 24 Jan 2016 15:23:37 +0100 Subject: [PATCH 085/229] Utility/Image: Fix tabs Former-commit-id: 4fd9be606d7cb356bdac14e9d8a9e23d493a549f --- src/Nazara/Utility/Image.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 8af7d7923..c8845f808 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1168,11 +1168,11 @@ namespace Nz EnsureOwnership(); Copy(m_sharedImage->levels[level].get(), pixels, PixelFormat::GetBytesPerPixel(m_sharedImage->format), - GetLevelSize(m_sharedImage->width, level), - GetLevelSize(m_sharedImage->height, level), - GetLevelSize(m_sharedImage->depth, level), - 0, 0, - srcWidth, srcHeight); + GetLevelSize(m_sharedImage->width, level), + GetLevelSize(m_sharedImage->height, level), + GetLevelSize(m_sharedImage->depth, level), + 0, 0, + srcWidth, srcHeight); return true; } From c46af20b5e8abea1cfc39be66682c15c1a5ccf31 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 24 Jan 2016 15:32:17 +0100 Subject: [PATCH 086/229] Build/SdkServer: Excludes Graphics Lua API file Former-commit-id: ae25551cf432eff08a505ad34b3332bf7ef79b88 --- build/scripts/tools/ndk_server.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index cbae533d6..1f8102a41 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -31,6 +31,7 @@ TOOL.FilesExclusion = { "../SDK/**/RenderSystem.*", "../SDK/**/LuaAPI_Audio.*", "../SDK/**/LuaAPI_Graphics.*", + "../SDK/**/LuaAPI_Renderer.*", } TOOL.Libraries = { From 90fe2528cf2c27085e952bba59d5023260914a51 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 27 Jan 2016 18:04:15 +0100 Subject: [PATCH 087/229] Fixes spaces Former-commit-id: 65f2e2f10aee0a47aff4b0166148745b13150001 --- include/Nazara/Core/MemoryStream.hpp | 3 +-- include/Nazara/Core/MemoryView.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 7328b7707..66197c8cc 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -26,7 +26,6 @@ namespace Nz bool EndOfStream() const override; - const ByteArray& GetBuffer() const; const UInt8* GetData() const; UInt64 GetCursorPos() const override; diff --git a/include/Nazara/Core/MemoryView.hpp b/include/Nazara/Core/MemoryView.hpp index e746ef47a..b8a689182 100644 --- a/include/Nazara/Core/MemoryView.hpp +++ b/include/Nazara/Core/MemoryView.hpp @@ -31,7 +31,7 @@ namespace Nz MemoryView& operator=(MemoryView&&) = delete; ///TODO private: - void FlushStream() override; + void FlushStream() override; std::size_t ReadBlock(void* buffer, std::size_t size) override; std::size_t WriteBlock(const void* buffer, std::size_t size) override; From 25a767290b27f43ab4c0acab376c12f0a299ea4f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 1 Feb 2016 13:24:49 +0100 Subject: [PATCH 090/229] Audio/OpenAL: Adjust return type of QueryInputDevices and QueryOutputDevices Former-commit-id: 5f2a07a73bc8903662139067ce0b484c9af86353 --- include/Nazara/Audio/OpenAL.hpp | 4 ++-- src/Nazara/Audio/OpenAL.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Audio/OpenAL.hpp b/include/Nazara/Audio/OpenAL.hpp index 812b002b6..5d6fa2634 100644 --- a/include/Nazara/Audio/OpenAL.hpp +++ b/include/Nazara/Audio/OpenAL.hpp @@ -73,8 +73,8 @@ namespace Nz static bool IsInitialized(); - static unsigned int QueryInputDevices(std::vector& devices); - static unsigned int QueryOutputDevices(std::vector& devices); + static std::size_t QueryInputDevices(std::vector& devices); + static std::size_t QueryOutputDevices(std::vector& devices); static bool SetDevice(const String& deviceName); diff --git a/src/Nazara/Audio/OpenAL.cpp b/src/Nazara/Audio/OpenAL.cpp index 72a56f7a7..1c30cd5f1 100644 --- a/src/Nazara/Audio/OpenAL.cpp +++ b/src/Nazara/Audio/OpenAL.cpp @@ -23,14 +23,14 @@ namespace Nz ALCcontext* s_context = nullptr; unsigned int s_version; - unsigned int ParseDevices(const char* deviceString, std::vector& devices) + std::size_t ParseDevices(const char* deviceString, std::vector& devices) { if (!deviceString) return 0; - unsigned int startSize = devices.size(); + std::size_t startSize = devices.size(); - unsigned int length; + std::size_t length; while ((length = std::strlen(deviceString)) > 0) { devices.push_back(String(deviceString, length)); @@ -222,7 +222,7 @@ namespace Nz return s_library.IsLoaded(); } - unsigned int OpenAL::QueryInputDevices(std::vector& devices) + std::size_t OpenAL::QueryInputDevices(std::vector& devices) { const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER)); if (!deviceString) @@ -231,7 +231,7 @@ namespace Nz return ParseDevices(deviceString, devices); } - unsigned int OpenAL::QueryOutputDevices(std::vector& devices) + std::size_t OpenAL::QueryOutputDevices(std::vector& devices) { const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); if (!deviceString) From e367ec456dcbf3af942848991af43355ce09e05f Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Feb 2016 18:42:19 +0100 Subject: [PATCH 091/229] Core: Rework Serialization Former-commit-id: d97eedbd3efc92235e3880ad061a5216fa77ebd7 --- include/Nazara/Core/Algorithm.hpp | 4 +- include/Nazara/Core/Algorithm.inl | 6 +- include/Nazara/Core/ByteStream.hpp | 65 +++++++++++++ include/Nazara/Core/ByteStream.inl | 129 ++++++++++++++++++++++++++ include/Nazara/Core/MemoryStream.hpp | 20 ++-- include/Nazara/Core/MemoryStream.inl | 26 +++++- include/Nazara/Core/MemoryView.hpp | 3 +- include/Nazara/Core/Serialization.hpp | 14 +-- include/Nazara/Core/Serializer.hpp | 46 --------- include/Nazara/Core/Serializer.inl | 67 ------------- include/Nazara/Core/String.hpp | 2 +- include/Nazara/Core/Unserializer.hpp | 44 --------- include/Nazara/Core/Unserializer.inl | 46 --------- src/Nazara/Core/ByteStream.cpp | 63 +++++++++++++ src/Nazara/Core/MemoryStream.cpp | 51 ++++------ src/Nazara/Core/MemoryView.cpp | 22 ++++- src/Nazara/Core/String.cpp | 2 +- 17 files changed, 337 insertions(+), 273 deletions(-) create mode 100644 include/Nazara/Core/ByteStream.hpp create mode 100644 include/Nazara/Core/ByteStream.inl delete mode 100644 include/Nazara/Core/Serializer.hpp delete mode 100644 include/Nazara/Core/Serializer.inl delete mode 100644 include/Nazara/Core/Unserializer.hpp delete mode 100644 include/Nazara/Core/Unserializer.inl create mode 100644 src/Nazara/Core/ByteStream.cpp diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 048c5d902..ae30f5065 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -41,10 +41,10 @@ namespace Nz template std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value); - inline bool Unserialize(UnserializationContext& context, bool* value); + inline bool Unserialize(SerializationContext& context, bool* value); template - std::enable_if_t::value, bool> Unserialize(UnserializationContext& context, T* value); + std::enable_if_t::value, bool> Unserialize(SerializationContext& context, T* value); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 5977c6d42..c66bdb046 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -131,10 +131,8 @@ namespace Nz return context.stream->Write(&value, sizeof(T)) == sizeof(T); } - inline bool Unserialize(UnserializationContext& context, bool* value) + inline bool Unserialize(SerializationContext& context, bool* value) { - NazaraAssert(value, "Invalid data pointer"); - if (context.currentBitPos == 8) { if (!Unserialize(context, &context.currentByte)) @@ -152,7 +150,7 @@ namespace Nz } template - std::enable_if_t::value, bool> Unserialize(UnserializationContext& context, T* value) + std::enable_if_t::value, bool> Unserialize(SerializationContext& context, T* value) { NazaraAssert(value, "Invalid data pointer"); diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp new file mode 100644 index 000000000..3b23a9f70 --- /dev/null +++ b/include/Nazara/Core/ByteStream.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_BYTESTREAM_HPP +#define NAZARA_BYTESTREAM_HPP + +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_CORE_API ByteStream + { + public: + inline ByteStream(Stream* stream = nullptr); + ByteStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite); + ByteStream(void* ptr, Nz::UInt64 size); + ByteStream(const void* ptr, Nz::UInt64 size); + ByteStream(const ByteStream&) = delete; + inline ByteStream(ByteStream&& stream); + ~ByteStream(); + + + inline Endianness GetDataEndianness() const; + inline Nz::UInt64 GetSize() const; + inline Stream* GetStream() const; + + inline bool FlushBits(); + + inline std::size_t Read(void* ptr, std::size_t size); + + inline void SetDataEndianness(Endianness endiannes); + inline void SetStream(Stream* stream); + void SetStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite); + void SetStream(void* ptr, Nz::UInt64 size); + void SetStream(const void* ptr, Nz::UInt64 size); + + inline void Write(const void* data, std::size_t size); + + template + ByteStream& operator>>(T& value); + + template + ByteStream& operator<<(const T& value); + + ByteStream& operator=(const ByteStream&) = delete; + inline ByteStream& operator=(ByteStream&&); + + private: + virtual void OnEmptyStream(); + + std::unique_ptr m_ownedStream; + SerializationContext m_context; + }; +} + +#include + +#endif // NAZARA_BYTESTREAM_HPP diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl new file mode 100644 index 000000000..f6e765175 --- /dev/null +++ b/include/Nazara/Core/ByteStream.inl @@ -0,0 +1,129 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + inline ByteStream::ByteStream(Stream* stream) + { + m_context.stream = stream; + } + + inline ByteStream::ByteStream(ByteStream&& stream) : + m_ownedStream(std::move(stream.m_ownedStream)), + m_context(stream.m_context) + { + stream.m_context.stream = nullptr; + } + + inline ByteStream::~ByteStream() + { + if (!FlushBits()) + NazaraWarning("Failed to flush bits at serializer destruction"); + } + + inline Endianness ByteStream::GetDataEndianness() const + { + return m_context.endianness; + } + + inline Nz::UInt64 ByteStream::GetSize() const + { + if (m_context.stream) + return m_context.stream->GetSize(); + else + return 0; + } + + inline Stream* ByteStream::GetStream() const + { + return m_context.stream; + } + + inline bool ByteStream::FlushBits() + { + if (!m_context.stream) + return true; + + if (m_context.currentBitPos != 8) + { + m_context.currentBitPos = 8; //< To prevent Serialize to flush bits itself + + if (!Serialize(m_context, m_context.currentByte)) + return false; + } + + return true; + } + + inline std::size_t ByteStream::Read(void* ptr, std::size_t size) + { + if (!m_context.stream) + OnEmptyStream(); + + FlushBits(); + return m_context.stream->Read(ptr, size); + } + + inline void ByteStream::SetDataEndianness(Endianness endiannes) + { + m_context.endianness = endiannes; + } + + inline void ByteStream::SetStream(Stream* stream) + { + // We don't want to lose some bits.. + FlushBits(); + + m_context.stream = stream; + m_ownedStream.reset(); + } + + inline void ByteStream::Write(const void* data, std::size_t size) + { + if (!m_context.stream) + OnEmptyStream(); + + FlushBits(); + m_context.stream->Write(data, size); + } + + template + ByteStream& ByteStream::operator>>(T& value) + { + if (!m_context.stream) + OnEmptyStream(); + + if (!Unserialize(m_context, &value)) + NazaraError("Failed to serialize value"); + + return *this; + } + + template + ByteStream& ByteStream::operator<<(const T& value) + { + if (!m_context.stream) + OnEmptyStream(); + + if (!Serialize(m_context, value)) + NazaraError("Failed to serialize value"); + + return *this; + } + + inline ByteStream& ByteStream::operator=(ByteStream&& stream) + { + m_context = stream.m_context; + m_ownedStream = std::move(stream.m_ownedStream); + + stream.m_context.stream = nullptr; + + return *this; + } +} + +#include diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 66197c8cc..f5d15fcf0 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -8,16 +8,17 @@ #define NAZARA_MEMORYSTREAM_HPP #include -#include #include namespace Nz { + class ByteArray; + class NAZARA_CORE_API MemoryStream : public Stream { public: - MemoryStream(); - MemoryStream(const void* ptr, unsigned int size); + inline MemoryStream(); + inline MemoryStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite); MemoryStream(const MemoryStream&) = default; MemoryStream(MemoryStream&&) = default; ~MemoryStream() = default; @@ -26,11 +27,12 @@ namespace Nz bool EndOfStream() const override; - const ByteArray& GetBuffer() const; - const UInt8* GetData() const; + inline ByteArray& GetBuffer(); + inline const ByteArray& GetBuffer() const; UInt64 GetCursorPos() const override; UInt64 GetSize() const override; + void SetBuffer(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite); bool SetCursorPos(UInt64 offset) override; MemoryStream& operator=(const MemoryStream&) = default; @@ -41,15 +43,9 @@ namespace Nz std::size_t ReadBlock(void* buffer, std::size_t size) override; std::size_t WriteBlock(const void* buffer, std::size_t size) override; - ByteArray m_buffer; + ByteArray* m_buffer; UInt64 m_pos; }; - - class AbstractHash; - - inline bool HashAppend(AbstractHash* hash, const String& string); - NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); - NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); } #include diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl index 61b2f0bb4..73514dcc4 100644 --- a/include/Nazara/Core/MemoryStream.inl +++ b/include/Nazara/Core/MemoryStream.inl @@ -2,13 +2,35 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include namespace Nz { - inline bool HashAppend(AbstractHash* hash, const MemoryStream& stream) + inline MemoryStream::MemoryStream() : + Stream(StreamOption_None, OpenMode_ReadWrite), + m_pos(0) { - return HashAppend(hash, stream.GetBuffer()); + } + + inline MemoryStream::MemoryStream(ByteArray* byteArray, UInt32 openMode) : + MemoryStream() + { + SetBuffer(byteArray, openMode); + } + + inline ByteArray& MemoryStream::GetBuffer() + { + NazaraAssert(m_buffer, "Invalid buffer"); + + return *m_buffer; + } + + inline const ByteArray& MemoryStream::GetBuffer() const + { + NazaraAssert(m_buffer, "Invalid buffer"); + + return *m_buffer; } } diff --git a/include/Nazara/Core/MemoryView.hpp b/include/Nazara/Core/MemoryView.hpp index b8a689182..41f4b1ee2 100644 --- a/include/Nazara/Core/MemoryView.hpp +++ b/include/Nazara/Core/MemoryView.hpp @@ -15,6 +15,7 @@ namespace Nz class NAZARA_CORE_API MemoryView : public Stream { public: + MemoryView(void* ptr, UInt64 size); MemoryView(const void* ptr, UInt64 size); MemoryView(const MemoryView&) = delete; MemoryView(MemoryView&&) = delete; ///TODO @@ -35,7 +36,7 @@ namespace Nz std::size_t ReadBlock(void* buffer, std::size_t size) override; std::size_t WriteBlock(const void* buffer, std::size_t size) override; - const UInt8* m_ptr; + UInt8* m_ptr; UInt64 m_pos; UInt64 m_size; }; diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/Serialization.hpp index 409aa6ace..47339b0a2 100644 --- a/include/Nazara/Core/Serialization.hpp +++ b/include/Nazara/Core/Serialization.hpp @@ -20,17 +20,9 @@ namespace Nz struct SerializationContext { Stream* stream; - Endianness endianness; - UInt8 currentBitPos; - UInt8 currentByte; - }; - - struct UnserializationContext - { - Stream* stream; - Endianness endianness; - UInt8 currentBitPos; - UInt8 currentByte; + Endianness endianness = Endianness_BigEndian; //< Default to Big Endian encoding + UInt8 currentBitPos = 8; //< 8 means no bit is currently wrote + UInt8 currentByte; //< Undefined value, will be initialized at the first bit write }; } diff --git a/include/Nazara/Core/Serializer.hpp b/include/Nazara/Core/Serializer.hpp deleted file mode 100644 index ae35f2254..000000000 --- a/include/Nazara/Core/Serializer.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_SERIALIZER_HPP -#define NAZARA_SERIALIZER_HPP - -#include -#include - -namespace Nz -{ - class Stream; - - class Serializer - { - public: - inline Serializer(Stream& stream); - Serializer(const Serializer&) = default; - Serializer(Serializer&&) = default; - ~Serializer(); - - inline Endianness GetDataEndianness() const; - inline Stream& GetStream() const; - - inline bool FlushBits(); - - inline void SetDataEndianness(Endianness endiannes); - inline void SetStream(Stream& stream); - - template - Serializer& operator<<(const T& value); - - Serializer& operator=(const Serializer&) = default; - Serializer& operator=(Serializer&&) = default; - - private: - SerializationContext m_serializationContext; - }; -} - -#include - -#endif // NAZARA_SERIALIZER_HPP diff --git a/include/Nazara/Core/Serializer.inl b/include/Nazara/Core/Serializer.inl deleted file mode 100644 index 69c433ad0..000000000 --- a/include/Nazara/Core/Serializer.inl +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include - -namespace Nz -{ - inline Serializer::Serializer(Stream& stream) - { - m_serializationContext.currentBitPos = 8; - m_serializationContext.endianness = Endianness_BigEndian; - m_serializationContext.stream = &stream; - } - - inline Serializer::~Serializer() - { - if (!FlushBits()) - NazaraWarning("Failed to flush bits at serializer destruction"); - } - - inline Endianness Serializer::GetDataEndianness() const - { - return m_serializationContext.endianness; - } - - inline Stream& Serializer::GetStream() const - { - return *m_serializationContext.stream; - } - - inline bool Serializer::FlushBits() - { - if (m_serializationContext.currentBitPos != 8) - { - m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself - - if (!Serialize(m_serializationContext, m_serializationContext.currentByte)) - return false; - } - - return true; - } - - inline void Serializer::SetDataEndianness(Endianness endiannes) - { - m_serializationContext.endianness = endiannes; - } - - inline void Serializer::SetStream(Stream& stream) - { - m_serializationContext.stream = &stream; - } - - template - Serializer& Serializer::operator<<(const T& value) - { - if (!Serialize(m_serializationContext, value)) - NazaraError("Failed to serialize value"); - - return *this; - } -} - -#include -#include "Serializer.hpp" diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 7cd26eaf4..a99326bf4 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -326,7 +326,7 @@ namespace Nz inline bool HashAppend(AbstractHash* hash, const String& string); NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); - NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); + NAZARA_CORE_API bool Unserialize(SerializationContext& context, String* string); } namespace std diff --git a/include/Nazara/Core/Unserializer.hpp b/include/Nazara/Core/Unserializer.hpp deleted file mode 100644 index 359fc1a7d..000000000 --- a/include/Nazara/Core/Unserializer.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_UNSERIALIZER_HPP -#define NAZARA_UNSERIALIZER_HPP - -#include -#include - -namespace Nz -{ - class Stream; - - class Unserializer - { - public: - inline Unserializer(Stream& stream); - Unserializer(const Unserializer&) = default; - Unserializer(Unserializer&&) = default; - ~Unserializer() = default; - - inline Endianness GetDataEndianness() const; - inline Stream& GetStream() const; - - inline void SetDataEndianness(Endianness endiannes); - inline void SetStream(Stream& stream); - - template - Unserializer& operator>>(T& value); - - Unserializer& operator=(const Unserializer&) = default; - Unserializer& operator=(Unserializer&&) = default; - - private: - UnserializationContext m_unserializationContext; - }; -} - -#include - -#endif // NAZARA_UNSERIALIZER_HPP diff --git a/include/Nazara/Core/Unserializer.inl b/include/Nazara/Core/Unserializer.inl deleted file mode 100644 index 3a832504a..000000000 --- a/include/Nazara/Core/Unserializer.inl +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include - -namespace Nz -{ - inline Unserializer::Unserializer(Stream& stream) - { - m_unserializationContext.currentBitPos = 8; - m_unserializationContext.endianness = Endianness_BigEndian; - m_unserializationContext.stream = &stream; - } - - inline Endianness Unserializer::GetDataEndianness() const - { - return m_unserializationContext.endianness; - } - - inline Stream& Unserializer::GetStream() const - { - return *m_unserializationContext.stream; - } - - inline void Unserializer::SetDataEndianness(Endianness endiannes) - { - m_unserializationContext.endianness = endiannes; - } - - inline void Unserializer::SetStream(Stream& stream) - { - m_unserializationContext.stream = &stream; - } - - template - Unserializer& Unserializer::operator>>(T& value) - { - if (!Unserialize(m_unserializationContext, &value)) - NazaraError("Failed to serialize value"); - - return *this; - } -} - -#include diff --git a/src/Nazara/Core/ByteStream.cpp b/src/Nazara/Core/ByteStream.cpp new file mode 100644 index 000000000..175212b48 --- /dev/null +++ b/src/Nazara/Core/ByteStream.cpp @@ -0,0 +1,63 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + ByteStream::ByteStream(ByteArray* byteArray, UInt32 openMode) : + ByteStream() + { + SetStream(byteArray, openMode); + } + + ByteStream::ByteStream(void* ptr, Nz::UInt64 size) : + ByteStream() + { + SetStream(ptr, size); + } + + ByteStream::ByteStream(const void* ptr, Nz::UInt64 size) : + ByteStream() + { + SetStream(ptr, size); + } + + void ByteStream::SetStream(ByteArray* byteArray, UInt32 openMode) + { + std::unique_ptr stream(new MemoryStream(byteArray, openMode)); + + SetStream(m_ownedStream.get()); + // SetStream reset our smart pointer, set it after calling it + m_ownedStream = std::move(stream); + } + + void ByteStream::SetStream(void* ptr, Nz::UInt64 size) + { + std::unique_ptr stream(new MemoryView(ptr, size)); + + SetStream(m_ownedStream.get()); + // SetStream reset our smart pointer, set it after calling it + m_ownedStream = std::move(stream); + } + + void ByteStream::SetStream(const void* ptr, Nz::UInt64 size) + { + std::unique_ptr stream(new MemoryView(ptr, size)); + + SetStream(m_ownedStream.get()); + // SetStream reset our smart pointer, set it after calling it + m_ownedStream = std::move(stream); + } + + void ByteStream::OnEmptyStream() + { + NazaraError("No stream"); + } +} diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index d141e2b15..b311cd058 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -3,39 +3,22 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include namespace Nz { - MemoryStream::MemoryStream() : - Stream(StreamOption_None, OpenMode_ReadWrite), - m_pos(0) - { - } - - MemoryStream::MemoryStream(const void* ptr, unsigned int size) : - MemoryStream() - { - m_buffer.Resize(size); - std::memcpy(m_buffer.GetBuffer(), ptr, size); - } - void MemoryStream::Clear() { - m_buffer.Clear(); + m_buffer->Clear(); m_pos = 0; } bool MemoryStream::EndOfStream() const { - return m_pos >= m_buffer.size(); - } - - const ByteArray& MemoryStream::GetBuffer() const - { - return m_buffer; + return m_pos >= m_buffer->size(); } UInt64 MemoryStream::GetCursorPos() const @@ -43,19 +26,20 @@ namespace Nz return m_pos; } - const UInt8* MemoryStream::GetData() const - { - return m_buffer.GetConstBuffer(); - } - UInt64 MemoryStream::GetSize() const { - return m_buffer.size(); + return m_buffer->GetSize(); + } + + void MemoryStream::SetBuffer(ByteArray* byteArray, UInt32 openMode) + { + m_buffer = byteArray; + m_openMode = openMode; } bool MemoryStream::SetCursorPos(UInt64 offset) { - m_pos = std::min(offset, m_buffer.size()); + m_pos = offset; return true; } @@ -67,10 +51,13 @@ namespace Nz std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size) { - std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); + if (EndOfStream()) + return 0; + + std::size_t readSize = std::min(size, static_cast(m_buffer->GetSize() - m_pos)); if (buffer) - std::memcpy(buffer, &m_buffer[m_pos], readSize); + std::memcpy(buffer, m_buffer->GetConstBuffer() + m_pos, readSize); m_pos += readSize; return readSize; @@ -79,10 +66,10 @@ namespace Nz std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size) { std::size_t endPos = static_cast(m_pos + size); - if (endPos > m_buffer.size()) - m_buffer.Resize(endPos); + if (endPos > m_buffer->GetSize()) + m_buffer->Resize(endPos); - std::memcpy(&m_buffer[m_pos], buffer, size); + std::memcpy(m_buffer->GetBuffer() + m_pos, buffer, size); m_pos = endPos; return size; diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index a630241d5..77c69bcb4 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -9,9 +9,17 @@ namespace Nz { + MemoryView::MemoryView(void* ptr, UInt64 size) : + Stream(StreamOption_None, OpenMode_ReadWrite), + m_ptr(reinterpret_cast(ptr)), + m_pos(0), + m_size(size) + { + } + MemoryView::MemoryView(const void* ptr, UInt64 size) : Stream(StreamOption_None, OpenMode_ReadOnly), - m_ptr(reinterpret_cast(ptr)), + m_ptr(reinterpret_cast(const_cast(ptr))), //< Okay, right, const_cast is bad, but this pointer is still read-only m_pos(0), m_size(size) { @@ -41,7 +49,7 @@ namespace Nz void MemoryView::FlushStream() { - NazaraInternalError("FlushStream has been called on a MemoryView"); + // Nothing to do } std::size_t MemoryView::ReadBlock(void* buffer, std::size_t size) @@ -57,7 +65,13 @@ namespace Nz std::size_t MemoryView::WriteBlock(const void* buffer, std::size_t size) { - NazaraInternalError("WriteBlock has been called on a MemoryView"); - return 0; + std::size_t endPos = static_cast(m_pos + size); + if (endPos > m_size) + size = m_size - m_pos; + + std::memcpy(&m_ptr[m_pos], buffer, size); + + m_pos += size; + return size; } } diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 76aa7510e..daa5cb85a 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4226,7 +4226,7 @@ namespace Nz return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize(); } - bool Unserialize(UnserializationContext& context, String* string) + bool Unserialize(SerializationContext& context, String* string) { UInt32 size; if (!Unserialize(context, &size)) From 89c796ed5ca858ccdff85cae0b44e8dcb7adef05 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Feb 2016 18:43:16 +0100 Subject: [PATCH 092/229] Core: Regenerate global header Former-commit-id: 5b357d76bc50862b19967346a77035f1fd65d30a --- include/Nazara/Core.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 50aecb311..a9a93d45c 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 20 Nov 2015 at 14:22:32 +// This file was automatically generated on 03 Feb 2016 at 00:06:56 /* Nazara Engine - Core module @@ -30,9 +30,11 @@ #define NAZARA_GLOBAL_CORE_HPP #include +#include #include #include #include +#include #include #include #include @@ -46,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -70,16 +74,15 @@ #include #include #include -#include #include #include +#include #include #include #include #include #include #include -#include #include #endif // NAZARA_GLOBAL_CORE_HPP From 4312de828e8f759a9a61e51fdad4a3cad015c46c Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Feb 2016 18:44:03 +0100 Subject: [PATCH 093/229] Network: Add NetPacket class Former-commit-id: 0c5acdbf9313621dddd3dcee23c6f85f46c27012 --- include/Nazara/Network/NetPacket.hpp | 71 +++++++++++++ include/Nazara/Network/NetPacket.inl | 20 ++++ src/Nazara/Network/NetPacket.cpp | 147 +++++++++++++++++++++++++++ src/Nazara/Network/Network.cpp | 8 ++ 4 files changed, 246 insertions(+) create mode 100644 include/Nazara/Network/NetPacket.hpp create mode 100644 include/Nazara/Network/NetPacket.inl create mode 100644 src/Nazara/Network/NetPacket.cpp diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp new file mode 100644 index 000000000..ff69fb2db --- /dev/null +++ b/include/Nazara/Network/NetPacket.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_NETPACKET_HPP +#define NAZARA_NETPACKET_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API NetPacket : public ByteStream + { + friend class Network; + + public: + NetPacket(); + NetPacket(UInt16 netCode, std::size_t sizeHint = 0); + NetPacket(UInt16 netCode, const void* ptr, std::size_t size); + NetPacket(const NetPacket&) = delete; + NetPacket(NetPacket&&) = default; + ~NetPacket(); + + inline UInt16 GetNetCode() const; + + virtual void OnReceive(UInt16 netCode, const void* data, std::size_t size); + virtual const void* OnSend(std::size_t* newSize) const; + + void Reset(); + void Reset(UInt16 netCode, std::size_t sizeHint = 0); + void Reset(UInt16 netCode, const void* ptr, std::size_t size); + + inline void SetNetCode(UInt16 netCode); + + NetPacket& operator=(const NetPacket&) = delete; + NetPacket& operator=(NetPacket&&) = default; + + static bool DecodeHeader(const void* data, UInt16* packetSize, UInt16* netCode); + static bool EncodeHeader(void* data, UInt16 packetSize, UInt16 netCode); + + static constexpr std::size_t HeaderSize = sizeof(UInt16) + sizeof(UInt16); //< PacketSize + NetCode + + private: + void OnEmptyStream() override; + + void FreeStream(); + void InitStream(std::size_t sizeHint, UInt64 cursorPos, UInt32 openMode); + + static bool Initialize(); + static void Uninitialize(); + + std::unique_ptr m_buffer; + MemoryStream m_memoryStream; + UInt16 m_netCode; + + static std::unique_ptr s_availableBuffersMutex; + static std::vector>> s_availableBuffers; + }; +} + +#include + +#endif // NAZARA_NETPACKET_HPP diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl new file mode 100644 index 000000000..62675af69 --- /dev/null +++ b/include/Nazara/Network/NetPacket.inl @@ -0,0 +1,20 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline UInt16 NetPacket::GetNetCode() const + { + return m_netCode; + } + + inline void NetPacket::SetNetCode(UInt16 netCode) + { + m_netCode = netCode; + } +} + +#include diff --git a/src/Nazara/Network/NetPacket.cpp b/src/Nazara/Network/NetPacket.cpp new file mode 100644 index 000000000..bf3b91618 --- /dev/null +++ b/src/Nazara/Network/NetPacket.cpp @@ -0,0 +1,147 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +namespace Nz +{ + NetPacket::NetPacket() : + m_netCode(NetCode_Invalid) + { + } + + NetPacket::NetPacket(UInt16 netCode, std::size_t sizeHint) + { + Reset(netCode, sizeHint); + } + + NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) + { + Reset(netCode, ptr, size); + } + + NetPacket::~NetPacket() + { + FreeStream(); + } + + void NetPacket::OnReceive(UInt16 netCode, const void* data, std::size_t size) + { + Reset(netCode, data, size); + } + + const void* NetPacket::OnSend(std::size_t* newSize) const + { + NazaraAssert(newSize, "Invalid size pointer"); + NazaraAssert(m_netCode != NetCode_Invalid, "Invalid NetCode"); + + std::size_t size = m_buffer->GetSize(); + if (!EncodeHeader(m_buffer->GetBuffer(), static_cast(size), m_netCode)) + { + NazaraError("Failed to encode packet header"); + return nullptr; + } + + *newSize = size; + return m_buffer->GetBuffer(); + } + + void NetPacket::Reset() + { + FreeStream(); + } + + void NetPacket::Reset(UInt16 netCode, std::size_t sizeHint) + { + InitStream(HeaderSize + sizeHint, HeaderSize, OpenMode_WriteOnly); + m_netCode = netCode; + } + + void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size) + { + InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly); + m_buffer->Resize(HeaderSize + size); + std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size); + + m_netCode = netCode; + } + + bool NetPacket::DecodeHeader(const void* data, UInt16* packetSize, UInt16* netCode) + { + MemoryView stream(data, HeaderSize); + + SerializationContext context; + context.stream = &stream; + + return Unserialize(context, packetSize) && Unserialize(context, netCode); + } + + bool NetPacket::EncodeHeader(void* data, UInt16 packetSize, UInt16 netCode) + { + MemoryView stream(data, HeaderSize); + + SerializationContext context; + context.stream = &stream; + + return Serialize(context, packetSize) && Serialize(context, netCode); + } + + void NetPacket::OnEmptyStream() + { + Reset(0); + } + + void NetPacket::FreeStream() + { + if (!m_buffer) + return; + + std::size_t size = m_buffer->GetSize(); + + Nz::LockGuard lock(*s_availableBuffersMutex); + s_availableBuffers.emplace_back(std::make_pair(size, std::move(m_buffer))); + } + + void NetPacket::InitStream(std::size_t sizeHint, UInt64 cursorPos, UInt32 openMode) + { + { + Nz::LockGuard lock(*s_availableBuffersMutex); + + FreeStream(); //< In case it wasn't released yet + + if (!s_availableBuffers.empty()) + { + m_buffer = std::move(s_availableBuffers.back().second); + s_availableBuffers.pop_back(); + } + } + + if (!m_buffer) + m_buffer = std::make_unique(); + + m_buffer->Resize(static_cast(cursorPos)); + m_memoryStream.SetBuffer(m_buffer.get(), openMode); + m_memoryStream.SetCursorPos(cursorPos); + SetStream(&m_memoryStream); + } + + bool NetPacket::Initialize() + { + s_availableBuffersMutex = std::make_unique(); + return true; + } + + void NetPacket::Uninitialize() + { + s_availableBuffers.clear(); + s_availableBuffersMutex.reset(); + } + + std::unique_ptr NetPacket::s_availableBuffersMutex; + std::vector>> NetPacket::s_availableBuffers; +} diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp index d2f0d0d51..72fa76517 100644 --- a/src/Nazara/Network/Network.cpp +++ b/src/Nazara/Network/Network.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -48,6 +49,12 @@ namespace Nz return false; } + if (!NetPacket::Initialize()) + { + NazaraError("Failed to initialize packets"); + return false; + } + onExit.Reset(); NazaraNotice("Initialized: Network module"); @@ -73,6 +80,7 @@ namespace Nz s_moduleReferenceCounter = 0; // Uninitialize module here + NetPacket::Uninitialize(); SocketImpl::Uninitialize(); NazaraNotice("Uninitialized: Network module"); From 00ed0e2ae318a5a3ab7a57629a94058f8659e6ef Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 12:24:44 +0100 Subject: [PATCH 094/229] Network/NetPacket: Inline some methods Former-commit-id: d54e7b9ff1baf93f6da35e29123d598b84742eac --- include/Nazara/Network/NetPacket.hpp | 15 +++++----- include/Nazara/Network/NetPacket.inl | 42 ++++++++++++++++++++++++++++ src/Nazara/Network/NetPacket.cpp | 41 --------------------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index ff69fb2db..f906a5431 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -13,7 +13,6 @@ #include #include #include -#include namespace Nz { @@ -22,21 +21,21 @@ namespace Nz friend class Network; public: - NetPacket(); - NetPacket(UInt16 netCode, std::size_t sizeHint = 0); - NetPacket(UInt16 netCode, const void* ptr, std::size_t size); + inline NetPacket(); + inline NetPacket(UInt16 netCode, std::size_t sizeHint = 0); + inline NetPacket(UInt16 netCode, const void* ptr, std::size_t size); NetPacket(const NetPacket&) = delete; NetPacket(NetPacket&&) = default; - ~NetPacket(); + inline ~NetPacket(); inline UInt16 GetNetCode() const; virtual void OnReceive(UInt16 netCode, const void* data, std::size_t size); virtual const void* OnSend(std::size_t* newSize) const; - void Reset(); - void Reset(UInt16 netCode, std::size_t sizeHint = 0); - void Reset(UInt16 netCode, const void* ptr, std::size_t size); + inline void Reset(); + inline void Reset(UInt16 netCode, std::size_t sizeHint = 0); + inline void Reset(UInt16 netCode, const void* ptr, std::size_t size); inline void SetNetCode(UInt16 netCode); diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index 62675af69..f0112dc47 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -3,14 +3,56 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include namespace Nz { + inline NetPacket::NetPacket() : + m_netCode(NetCode_Invalid) + { + } + + inline NetPacket::NetPacket(UInt16 netCode, std::size_t sizeHint) + { + Reset(netCode, sizeHint); + } + + inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) + { + Reset(netCode, ptr, size); + } + + inline NetPacket::~NetPacket() + { + FreeStream(); + } + inline UInt16 NetPacket::GetNetCode() const { return m_netCode; } + inline void NetPacket::Reset() + { + FreeStream(); + } + + inline void NetPacket::Reset(UInt16 netCode, std::size_t sizeHint) + { + InitStream(HeaderSize + sizeHint, HeaderSize, OpenMode_WriteOnly); + m_netCode = netCode; + } + + inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size) + { + InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly); + m_buffer->Resize(HeaderSize + size); + std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size); + + m_netCode = netCode; + } + inline void NetPacket::SetNetCode(UInt16 netCode) { m_netCode = netCode; diff --git a/src/Nazara/Network/NetPacket.cpp b/src/Nazara/Network/NetPacket.cpp index bf3b91618..f9e305e14 100644 --- a/src/Nazara/Network/NetPacket.cpp +++ b/src/Nazara/Network/NetPacket.cpp @@ -5,31 +5,10 @@ #include #include #include -#include #include namespace Nz { - NetPacket::NetPacket() : - m_netCode(NetCode_Invalid) - { - } - - NetPacket::NetPacket(UInt16 netCode, std::size_t sizeHint) - { - Reset(netCode, sizeHint); - } - - NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) - { - Reset(netCode, ptr, size); - } - - NetPacket::~NetPacket() - { - FreeStream(); - } - void NetPacket::OnReceive(UInt16 netCode, const void* data, std::size_t size) { Reset(netCode, data, size); @@ -51,26 +30,6 @@ namespace Nz return m_buffer->GetBuffer(); } - void NetPacket::Reset() - { - FreeStream(); - } - - void NetPacket::Reset(UInt16 netCode, std::size_t sizeHint) - { - InitStream(HeaderSize + sizeHint, HeaderSize, OpenMode_WriteOnly); - m_netCode = netCode; - } - - void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size) - { - InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly); - m_buffer->Resize(HeaderSize + size); - std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size); - - m_netCode = netCode; - } - bool NetPacket::DecodeHeader(const void* data, UInt16* packetSize, UInt16* netCode) { MemoryView stream(data, HeaderSize); From 0b71d1a2e21b23fca1ef4371d20540b0625f77df Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 12:43:50 +0100 Subject: [PATCH 095/229] Network/NetPacket: Make new packets ReadWrite Former-commit-id: e9735766181932fbd9840b6f143ba133b2a5c08f --- include/Nazara/Network/NetPacket.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index f0112dc47..23825966f 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -40,7 +40,7 @@ namespace Nz inline void NetPacket::Reset(UInt16 netCode, std::size_t sizeHint) { - InitStream(HeaderSize + sizeHint, HeaderSize, OpenMode_WriteOnly); + InitStream(HeaderSize + sizeHint, HeaderSize, OpenMode_ReadWrite); m_netCode = netCode; } From 4e3244c999166bc989349efde439fcfe1dc4ea91 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 12:48:04 +0100 Subject: [PATCH 096/229] Network: Add NetCode enum and SocketError_Packet, fixes compilation Former-commit-id: 2c56f086a7b8892377730e4f556f3953e9e7dc62 --- include/Nazara/Core/ByteStream.hpp | 1 - include/Nazara/Network/Enums.hpp | 64 ++++++++++++++++-------------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp index 3b23a9f70..e26382cf4 100644 --- a/include/Nazara/Core/ByteStream.hpp +++ b/include/Nazara/Core/ByteStream.hpp @@ -26,7 +26,6 @@ namespace Nz inline ByteStream(ByteStream&& stream); ~ByteStream(); - inline Endianness GetDataEndianness() const; inline Nz::UInt64 GetSize() const; inline Stream* GetStream() const; diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 21c96dde4..6fbb5aff3 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -9,20 +9,9 @@ namespace Nz { - enum ResolveError + enum NetCode : UInt16 { - ResolveError_NoError, - - ResolveError_Internal, //< An internal error occured - ResolveError_ResourceError, //< The operating system lacks the resources to proceed (insufficient memory) - ResolveError_NonRecoverable, //< An nonrecoverable error occured - ResolveError_NotFound, //< No such host is known - ResolveError_NotInitialized, //< Nazara network has not been initialized - ResolveError_ProtocolNotSupported, //< A specified protocol is not supported by the server - ResolveError_TemporaryFailure, //< A temporary failure occured, try again - ResolveError_Unknown, //< The last operation failed with an unlisted error code - - ResolveError_Max = ResolveError_TemporaryFailure + NetCode_Invalid = 0x0000 }; enum NetProtocol @@ -35,25 +24,42 @@ namespace Nz NetProtocol_Max = NetProtocol_Unknown }; + enum ResolveError + { + ResolveError_NoError, + + ResolveError_Internal, //< An internal error occurred + ResolveError_ResourceError, //< The operating system lacks the resources to proceed (insufficient memory) + ResolveError_NonRecoverable, //< An nonrecoverable error occurred + ResolveError_NotFound, //< No such host is known + ResolveError_NotInitialized, //< Nazara network has not been initialized + ResolveError_ProtocolNotSupported, //< A specified protocol is not supported by the server + ResolveError_TemporaryFailure, //< A temporary failure occurred, try again + ResolveError_Unknown, //< The last operation failed with an unlisted error code + + ResolveError_Max = ResolveError_Unknown + }; + enum SocketError { SocketError_NoError, - SocketError_AddressNotAvailable, //< The address is already in use (when binding/listening) - SocketError_ConnectionClosed, //< The connection has been closed - SocketError_ConnectionRefused, //< The connection attempt was refused - SocketError_DatagramSize, //< The datagram size is over the system limit - SocketError_Internal, //< The error is coming from the engine - SocketError_NetworkError, //< The network system has failed (maybe network is down) - SocketError_NotInitialized, //< Nazara network has not been initialized - SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adaptater) - SocketError_ResolveError, //< The hostname couldn't be resolved (more information in ResolveError code) - SocketError_ResourceError, //< The operating system lacks the resources to proceed (e.g. memory/socket descriptor) - SocketError_UnreachableHost, //< The host is not reachable - SocketError_TimedOut, //< The operation timed out - SocketError_Unknown, //< The last operation failed with an unlisted error code - - SocketError_Max = SocketError_Unknown + SocketError_AddressNotAvailable, //< The address is already in use (when binding/listening) + SocketError_ConnectionClosed, //< The connection has been closed + SocketError_ConnectionRefused, //< The connection attempt was refused + SocketError_DatagramSize, //< The datagram size is over the system limit + SocketError_Internal, //< The error is coming from the engine + SocketError_Packet, //< The packet encoding/decoding failed, probably because of corrupted data + SocketError_NetworkError, //< The network system has failed (maybe network is down) + SocketError_NotInitialized, //< Nazara network has not been initialized + SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adaptater) + SocketError_ResolveError, //< The hostname couldn't be resolved (more information in ResolveError code) + SocketError_ResourceError, //< The operating system lacks the resources to proceed (e.g. memory/socket descriptor) + SocketError_TimedOut, //< The operation timed out + SocketError_Unknown, //< The last operation failed with an unlisted error code + SocketError_UnreachableHost, //< The host is not reachable + + SocketError_Max = SocketError_UnreachableHost }; enum SocketState @@ -62,7 +68,7 @@ namespace Nz SocketState_Connecting, //< The socket is currently connecting SocketState_Connected, //< The socket is currently connected SocketState_NotConnected, //< The socket is not connected (or has been disconnected) - SocketState_Resolving, //< The socket is currently resolving a hostname + SocketState_Resolving, //< The socket is currently resolving a host name SocketState_Max = SocketState_NotConnected }; From 33e2bb905b5afd68e6de68d24d0e1d6cd3f82db4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 13:24:08 +0100 Subject: [PATCH 097/229] Network/NetPacket: Add Get(Const)Data method Former-commit-id: 53f4f230b3e7baa65c79d97b21e192108b771312 --- include/Nazara/Network/NetPacket.hpp | 2 ++ include/Nazara/Network/NetPacket.inl | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index f906a5431..1f950606b 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -28,6 +28,8 @@ namespace Nz NetPacket(NetPacket&&) = default; inline ~NetPacket(); + inline const UInt8* GetConstData() const; + inline UInt8* GetData() const; inline UInt16 GetNetCode() const; virtual void OnReceive(UInt16 netCode, const void* data, std::size_t size); diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index 23825966f..198354732 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -2,9 +2,10 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include +#include namespace Nz { @@ -28,6 +29,20 @@ namespace Nz FreeStream(); } + inline const UInt8* NetPacket::GetConstData() const + { + NazaraAssert(m_buffer, "Invalid buffer"); + + return m_buffer->GetConstBuffer(); + } + + inline UInt8* NetPacket::GetData() const + { + NazaraAssert(m_buffer, "Invalid buffer"); + + return m_buffer->GetBuffer(); + } + inline UInt16 NetPacket::GetNetCode() const { return m_netCode; From f723d6a29cc7d2c460ec8ab670aafcfe9a265023 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 13:27:06 +0100 Subject: [PATCH 098/229] Network: Replace unsigned int by size_t for size Former-commit-id: efa7e2f50ae370f96871726be7906332ca8969a4 --- include/Nazara/Network/AbstractSocket.hpp | 2 +- include/Nazara/Network/UdpSocket.hpp | 2 +- src/Nazara/Network/AbstractSocket.cpp | 2 +- src/Nazara/Network/Posix/SocketImpl.cpp | 6 +++--- src/Nazara/Network/Posix/SocketImpl.hpp | 6 +++--- src/Nazara/Network/UdpSocket.cpp | 5 +++-- src/Nazara/Network/Win32/SocketImpl.cpp | 2 +- src/Nazara/Network/Win32/SocketImpl.hpp | 4 ++-- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index 7b8327cb1..5bd91d807 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -33,7 +33,7 @@ namespace Nz inline bool IsBlockingEnabled() const; - unsigned int QueryAvailableBytes() const; + std::size_t QueryAvailableBytes() const; AbstractSocket& operator=(const AbstractSocket&) = delete; AbstractSocket& operator=(AbstractSocket&& abstractSocket); diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index e6577bec7..815f88fc8 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -34,7 +34,7 @@ namespace Nz inline bool IsBroadcastingEnabled() const; - unsigned int QueryMaxDatagramSize(); + std::size_t QueryMaxDatagramSize(); bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received); diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index c24ae43f9..bec0cdf84 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -63,7 +63,7 @@ namespace Nz } } - unsigned int AbstractSocket::QueryAvailableBytes() const + std::size_t AbstractSocket::QueryAvailableBytes() const { if (m_handle == SocketImpl::InvalidHandle) return 0; diff --git a/src/Nazara/Network/Posix/SocketImpl.cpp b/src/Nazara/Network/Posix/SocketImpl.cpp index cf5a638cf..c2cf3a6f8 100644 --- a/src/Nazara/Network/Posix/SocketImpl.cpp +++ b/src/Nazara/Network/Posix/SocketImpl.cpp @@ -224,7 +224,7 @@ namespace Nz return code; } - SocketState SocketImpl::Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error) + SocketState SocketImpl::Listen(SocketHandle handle, const IpAddress& address, unsigned int queueSize, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); NazaraAssert(address.IsValid(), "Invalid address"); @@ -254,7 +254,7 @@ namespace Nz return SocketState_Bound; } - unsigned int SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error) + std::size_t SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); @@ -311,7 +311,7 @@ namespace Nz return code; } - unsigned int SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) + std::size_t SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) { unsigned int code; unsigned int codeLength = sizeof(code); diff --git a/src/Nazara/Network/Posix/SocketImpl.hpp b/src/Nazara/Network/Posix/SocketImpl.hpp index c23b4d3e4..8896ce597 100644 --- a/src/Nazara/Network/Posix/SocketImpl.hpp +++ b/src/Nazara/Network/Posix/SocketImpl.hpp @@ -32,12 +32,12 @@ namespace Nz static int GetLastErrorCode(); static int GetLastErrorCode(SocketHandle handle, SocketError* error = nullptr); - static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error); + static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned int queueSize, SocketError* error); - static unsigned int QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); static bool QueryBroadcasting(SocketHandle handle, SocketError* error = nullptr); static bool QueryKeepAlive(SocketHandle handle, SocketError* error = nullptr); - static unsigned int QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); static bool QueryNoDelay(SocketHandle handle, SocketError* error = nullptr); static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index 0ecd423bb..88f9f10c0 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -13,6 +12,8 @@ #error Missing implementation: Socket #endif +#include + namespace Nz { SocketState UdpSocket::Bind(const IpAddress& address) @@ -39,7 +40,7 @@ namespace Nz } } - unsigned int UdpSocket::QueryMaxDatagramSize() + std::size_t UdpSocket::QueryMaxDatagramSize() { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index fb788f0e6..1c5ee7ad0 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -256,7 +256,7 @@ namespace Nz return SocketState_Bound; } - unsigned int SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error) + std::size_t SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp index 8f6b1f72d..dc0d77e73 100644 --- a/src/Nazara/Network/Win32/SocketImpl.hpp +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -35,10 +35,10 @@ namespace Nz static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error); - static unsigned int QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); static bool QueryBroadcasting(SocketHandle handle, SocketError* error = nullptr); static bool QueryKeepAlive(SocketHandle handle, SocketError* error = nullptr); - static unsigned int QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); static bool QueryNoDelay(SocketHandle handle, SocketError* error = nullptr); static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); From 6c0215952d3dbdbe8b1f29b45f8ded2f38a853fd Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 14:40:40 +0100 Subject: [PATCH 099/229] Network/NetPacket: Add Resize method and fix buffer size Former-commit-id: 465864559149ef62279038c24649d73c75f38037 --- include/Nazara/Network/NetPacket.hpp | 8 +++++--- include/Nazara/Network/NetPacket.inl | 16 ++++++++++++---- src/Nazara/Network/NetPacket.cpp | 8 ++++++-- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index 1f950606b..83815b0fe 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -22,7 +22,7 @@ namespace Nz public: inline NetPacket(); - inline NetPacket(UInt16 netCode, std::size_t sizeHint = 0); + inline NetPacket(UInt16 netCode, std::size_t minSize = 0); inline NetPacket(UInt16 netCode, const void* ptr, std::size_t size); NetPacket(const NetPacket&) = delete; NetPacket(NetPacket&&) = default; @@ -36,9 +36,11 @@ namespace Nz virtual const void* OnSend(std::size_t* newSize) const; inline void Reset(); - inline void Reset(UInt16 netCode, std::size_t sizeHint = 0); + inline void Reset(UInt16 netCode, std::size_t minSize = 0); inline void Reset(UInt16 netCode, const void* ptr, std::size_t size); + inline void Resize(std::size_t newSize); + inline void SetNetCode(UInt16 netCode); NetPacket& operator=(const NetPacket&) = delete; @@ -53,7 +55,7 @@ namespace Nz void OnEmptyStream() override; void FreeStream(); - void InitStream(std::size_t sizeHint, UInt64 cursorPos, UInt32 openMode); + void InitStream(std::size_t minSize, UInt64 cursorPos, UInt32 openMode); static bool Initialize(); static void Uninitialize(); diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index 198354732..1fdf6c6ee 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -14,9 +14,9 @@ namespace Nz { } - inline NetPacket::NetPacket(UInt16 netCode, std::size_t sizeHint) + inline NetPacket::NetPacket(UInt16 netCode, std::size_t minSize) { - Reset(netCode, sizeHint); + Reset(netCode, minSize); } inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) @@ -26,6 +26,7 @@ namespace Nz inline NetPacket::~NetPacket() { + FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it FreeStream(); } @@ -53,9 +54,9 @@ namespace Nz FreeStream(); } - inline void NetPacket::Reset(UInt16 netCode, std::size_t sizeHint) + inline void NetPacket::Reset(UInt16 netCode, std::size_t minSize) { - InitStream(HeaderSize + sizeHint, HeaderSize, OpenMode_ReadWrite); + InitStream(HeaderSize + minSize, HeaderSize, OpenMode_ReadWrite); m_netCode = netCode; } @@ -68,6 +69,13 @@ namespace Nz m_netCode = netCode; } + inline void NetPacket::Resize(std::size_t newSize) + { + NazaraAssert(m_buffer, "Invalid buffer"); + + m_buffer->Resize(newSize); + } + inline void NetPacket::SetNetCode(UInt16 netCode) { m_netCode = netCode; diff --git a/src/Nazara/Network/NetPacket.cpp b/src/Nazara/Network/NetPacket.cpp index f9e305e14..e0c5b3df8 100644 --- a/src/Nazara/Network/NetPacket.cpp +++ b/src/Nazara/Network/NetPacket.cpp @@ -66,8 +66,10 @@ namespace Nz s_availableBuffers.emplace_back(std::make_pair(size, std::move(m_buffer))); } - void NetPacket::InitStream(std::size_t sizeHint, UInt64 cursorPos, UInt32 openMode) + void NetPacket::InitStream(std::size_t minSize, UInt64 cursorPos, UInt32 openMode) { + NazaraAssert(minSize >= cursorPos, "Cannot init stream with a smaller size than wanted cursor pos"); + { Nz::LockGuard lock(*s_availableBuffersMutex); @@ -83,7 +85,9 @@ namespace Nz if (!m_buffer) m_buffer = std::make_unique(); - m_buffer->Resize(static_cast(cursorPos)); + if (m_buffer->GetSize() < minSize) + m_buffer->Resize(minSize); + m_memoryStream.SetBuffer(m_buffer.get(), openMode); m_memoryStream.SetCursorPos(cursorPos); SetStream(&m_memoryStream); From 08caff5ea337a21391d61459e8bff5432769d150 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Feb 2016 14:51:26 +0100 Subject: [PATCH 100/229] Network: Add support for sending/receiving NetPacket over UDP/TCP Former-commit-id: 5c09a5fa8b499e4204d2312f6d04d8554093a5a4 --- include/Nazara/Network/TcpClient.hpp | 16 +++++- include/Nazara/Network/UdpSocket.hpp | 4 ++ src/Nazara/Network/TcpClient.cpp | 80 +++++++++++++++++++++++++++- src/Nazara/Network/UdpSocket.cpp | 52 ++++++++++++++++++ 4 files changed, 149 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index cbf501ffe..fda4671f9 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -8,6 +8,7 @@ #define NAZARA_TCPCLIENT_HPP #include +#include #include #include #include @@ -15,6 +16,8 @@ namespace Nz { + class NetPacket; + class NAZARA_NETWORK_API TcpClient : public AbstractSocket, public Stream { friend class TcpServer; @@ -43,8 +46,10 @@ namespace Nz inline bool IsKeepAliveEnabled() const; bool Receive(void* buffer, std::size_t size, std::size_t* received); + bool ReceivePacket(NetPacket* packet); bool Send(const void* buffer, std::size_t size, std::size_t* sent); + bool SendPacket(const NetPacket& packet); bool SetCursorPos(UInt64 offset) override; @@ -62,7 +67,16 @@ namespace Nz void Reset(SocketHandle handle, const IpAddress& peerAddress); std::size_t WriteBlock(const void* buffer, std::size_t size) override; + struct PendingPacket + { + std::size_t received = 0; + ByteArray data; + UInt16 netcode; + bool headerReceived = false; + }; + IpAddress m_peerAddress; + PendingPacket m_pendingPacket; UInt64 m_keepAliveInterval; UInt64 m_keepAliveTime; bool m_isLowDelayEnabled; @@ -72,4 +86,4 @@ namespace Nz #include -#endif // NAZARA_TCPCLIENT_HPP \ No newline at end of file +#endif // NAZARA_TCPCLIENT_HPP diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index 815f88fc8..96c391436 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -13,6 +13,8 @@ namespace Nz { + class NetPacket; + class NAZARA_NETWORK_API UdpSocket : public AbstractSocket { public: @@ -37,8 +39,10 @@ namespace Nz std::size_t QueryMaxDatagramSize(); bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received); + bool ReceivePacket(NetPacket* packet, IpAddress* from); bool Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent); + bool SendPacket(const IpAddress& to, const NetPacket& packet); private: void OnClose() override; diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 6bb26aef8..267e5f67a 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -16,6 +16,8 @@ #error Missing implementation: Socket #endif +#include + namespace Nz { SocketState TcpClient::Connect(const IpAddress& remoteAddress) @@ -141,6 +143,66 @@ namespace Nz return true; } + bool TcpClient::ReceivePacket(NetPacket* packet) + { + //TODO: Every packet requires at least two Receive call, using an internal buffer of a fixed size would prevent this + NazaraAssert(packet, "Invalid packet"); + + if (!m_pendingPacket.headerReceived) + { + m_pendingPacket.data.Resize(NetPacket::HeaderSize); + + std::size_t received; + if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], NetPacket::HeaderSize - m_pendingPacket.received, &received)) + return false; + + m_pendingPacket.received += received; + + NazaraAssert(m_pendingPacket.received <= NetPacket::HeaderSize, "Received more data than header size"); + if (m_pendingPacket.received >= NetPacket::HeaderSize) + { + UInt16 size; + if (!NetPacket::DecodeHeader(m_pendingPacket.data.GetConstBuffer(), &size, &m_pendingPacket.netcode)) + { + m_lastError = SocketError_Packet; + NazaraWarning("Invalid header data"); + return false; + } + + m_pendingPacket.data.Resize(size - NetPacket::HeaderSize); + m_pendingPacket.headerReceived = true; + m_pendingPacket.received = 0; + } + } + + // We may have just received the header now + if (m_pendingPacket.headerReceived) + { + UInt16 packetSize = static_cast(m_pendingPacket.data.GetSize()); //< Total packet size + + std::size_t received; + if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received)) + return false; + + m_pendingPacket.received += received; + + NazaraAssert(m_pendingPacket.received <= packetSize, "Received more data than packet size"); + if (m_pendingPacket.received >= packetSize) + { + // Okay we received the whole packet, copy it + packet->Reset(m_pendingPacket.netcode, m_pendingPacket.data.GetConstBuffer(), m_pendingPacket.data.GetSize()); + + // And reset every state + m_pendingPacket.data.Clear(); + m_pendingPacket.headerReceived = false; + m_pendingPacket.received = 0; + return true; + } + } + + return false; + } + bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -183,6 +245,20 @@ namespace Nz return true; } + bool TcpClient::SendPacket(const NetPacket& packet) + { + std::size_t size = 0; + const UInt8* ptr = static_cast(packet.OnSend(&size)); + if (!ptr) + { + m_lastError = SocketError_Packet; + NazaraError("Failed to prepare packet"); + return false; + } + + return Send(ptr, size, nullptr); + } + bool TcpClient::SetCursorPos(UInt64 offset) { NazaraError("SetCursorPos() cannot be used on sequential streams"); @@ -215,7 +291,7 @@ namespace Nz } SocketState newState = SocketImpl::Connect(m_handle, m_peerAddress, msTimeout, &m_lastError); - NazaraAssert(newState != SocketState_Connecting, "Invalid internal return"); + NazaraAssert(newState != SocketState_Connecting, "Invalid internal return"); //< Connect cannot return Connecting is a timeout was specified // Prevent valid peer address in non-connected state if (newState == SocketState_NotConnected) diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index 88f9f10c0..d8461c627 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -61,6 +62,43 @@ namespace Nz return true; } + bool UdpSocket::ReceivePacket(NetPacket* packet, IpAddress* from) + { + // I'm not sure what's the best between having a 65k bytes buffer ready for any datagram size + // or querying the next datagram size every time, for now I'll leave it as is + packet->Reset(NetCode_Invalid, std::numeric_limits::max()); + + std::size_t received; + if (!Receive(packet->GetData(), static_cast(packet->GetSize()), from, &received)) + { + NazaraError("Failed to receive packet"); + return false; + } + + if (received == 0) + return false; //< No datagram received + + Nz::UInt16 netCode; + Nz::UInt16 packetSize; + if (!NetPacket::DecodeHeader(packet->GetConstData(), &packetSize, &netCode)) + { + m_lastError = SocketError_Packet; + NazaraWarning("Invalid header data"); + return false; + } + + if (packetSize != received) + { + m_lastError = SocketError_Packet; + NazaraWarning("Invalid packet size (packet size is " + String::Number(packetSize) + " bytes, received " + Nz::String::Number(received) + " bytes)"); + return false; + } + + packet->Resize(received); + packet->SetNetCode(netCode); + return true; + } + bool UdpSocket::Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent) { NazaraAssert(to.IsValid(), "Invalid ip address"); @@ -77,6 +115,20 @@ namespace Nz return true; } + bool UdpSocket::SendPacket(const IpAddress& to, const NetPacket& packet) + { + std::size_t size = 0; + const UInt8* ptr = static_cast(packet.OnSend(&size)); + if (!ptr) + { + m_lastError = SocketError_Packet; + NazaraError("Failed to prepare packet"); + return false; + } + + return Send(to, ptr, size, nullptr); + } + void UdpSocket::OnClose() { AbstractSocket::OnClose(); From 0934c2196743372c940b1a1626f7ceca39214336 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:19:40 +0100 Subject: [PATCH 101/229] Documentation for AbstractHash Former-commit-id: 467b96c5d8b9ed9a3fddd7cf6f09803977b53caf --- src/Nazara/Core/AbstractHash.cpp | 36 +++++++++++++++++++++--------- tests/Engine/Core/AbstractHash.cpp | 27 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 tests/Engine/Core/AbstractHash.cpp diff --git a/src/Nazara/Core/AbstractHash.cpp b/src/Nazara/Core/AbstractHash.cpp index f0e82bb19..60f2f42cb 100644 --- a/src/Nazara/Core/AbstractHash.cpp +++ b/src/Nazara/Core/AbstractHash.cpp @@ -17,8 +17,24 @@ namespace Nz { + /*! + * \class Nz::AbstractHash + * \brief Core class that represents the behaviour of the hash classes + * + * \remark This class is abstract + */ + AbstractHash::~AbstractHash() = default; + /*! + * \brief Factory of Hash classes in function of HashType + * \return A new instance of the Hash class according to the HashType + * + * \param type Enumeration of type HashType + * + * \remark If enumeration is not defined in HashType, a NazaraInternalError is thrown and nullptr is returned + */ + std::unique_ptr AbstractHash::Get(HashType type) { NazaraAssert(type <= HashType_Max, "Hash type value out of enum"); @@ -26,34 +42,34 @@ namespace Nz switch (type) { case HashType_Fletcher16: - return std::unique_ptr(new HashFletcher16); + return std::make_unique(); case HashType_CRC32: - return std::unique_ptr(new HashCRC32); + return std::make_unique(); case HashType_MD5: - return std::unique_ptr(new HashMD5); + return std::make_unique(); case HashType_SHA1: - return std::unique_ptr(new HashSHA1); + return std::make_unique(); case HashType_SHA224: - return std::unique_ptr(new HashSHA224); + return std::make_unique(); case HashType_SHA256: - return std::unique_ptr(new HashSHA256); + return std::make_unique(); case HashType_SHA384: - return std::unique_ptr(new HashSHA384); + return std::make_unique(); case HashType_SHA512: - return std::unique_ptr(new HashSHA512); + return std::make_unique(); case HashType_Whirlpool: - return std::unique_ptr(new HashWhirlpool); + return std::make_unique(); } NazaraInternalError("Hash type not handled (0x" + String::Number(type, 16) + ')'); - return std::unique_ptr(); + return nullptr; } } diff --git a/tests/Engine/Core/AbstractHash.cpp b/tests/Engine/Core/AbstractHash.cpp new file mode 100644 index 000000000..bcb47fc33 --- /dev/null +++ b/tests/Engine/Core/AbstractHash.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include + +#include + +SCENARIO("AbstractHash", "[CORE][ABSTRACTHASH]") +{ + GIVEN("The hash SHA512") + { + std::unique_ptr SHA512 = Nz::AbstractHash::Get(Nz::HashType_SHA512); + SHA512->Begin(); + + WHEN("We introduce data") + { + std::array array{ 0, 1, 2, 3 }; + SHA512->Append(array.begin(), array.size()); + + THEN("We ask for the bytearray") + { + Nz::ByteArray byteArray = SHA512->End(); + REQUIRE(byteArray.GetSize() == SHA512->GetDigestLength()); + } + } + } +} From d3621c82eb42fbf52a760168fea26d371066716d Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:20:16 +0100 Subject: [PATCH 102/229] Documentation for Algorithm Former-commit-id: a2090cb6f5e7373f4d9adc3c1d5067619b1bd185 --- include/Nazara/Core/Algorithm.hpp | 10 +-- include/Nazara/Core/Algorithm.inl | 126 ++++++++++++++++++++++++++-- tests/Engine/Core/AlgorithmCore.cpp | 40 +++++++++ 3 files changed, 164 insertions(+), 12 deletions(-) create mode 100644 tests/Engine/Core/AlgorithmCore.cpp diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index ae30f5065..5f8b8aa7f 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -27,11 +27,11 @@ namespace Nz template std::size_t CountOf(const T& c); template void HashCombine(std::size_t& seed, const T& v); - template - struct PointedType - { - using type = void; //< FIXME: I can't make SFINAE work - }; + template + struct PointedType + { + using type = void; //< FIXME: I can't make SFINAE work + }; template struct TypeTag {}; diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index c66bdb046..a9855c62c 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -30,6 +30,16 @@ namespace Nz } } + /*! + * \brief Applies the tuple to the function + * \return The result of the function + * + * \param fn Function + * \param t Tuple of arguments for the function + * + * \see Apply + */ + template auto Apply(F&& fn, Tuple&& t) { @@ -38,6 +48,17 @@ namespace Nz return Detail::ApplyImplFunc(std::forward(fn), std::forward(t), std::make_index_sequence()); } + /*! + * \brief Applies the tuple to the member function on an object + * \return The result of the member function called + * + * \param object Object of a class + * \param fn Member function + * \param t Tuple of arguments for the member function + * + * \see Apply + */ + template auto Apply(O& object, F&& fn, Tuple&& t) { @@ -46,15 +67,39 @@ namespace Nz return Detail::ApplyImplMethod(object, std::forward(fn), std::forward(t), std::make_index_sequence()); } + /*! + * \brief Computes the hash of a hashable object + * \return A bytearray which represents the hash + * + * \param hash Enumeration of type HashType + * \param v Object to hash, must be convertible to "Nz::String" + * + * \see ComputeHash + */ + template ByteArray ComputeHash(HashType hash, const T& v) { return ComputeHash(AbstractHash::Get(hash).get(), v); } + /*! + * \brief Computes the hash of a hashable object + * \return A bytearray which represents the hash + * + * \param hash Pointer to abstract hash + * \param v Object to hash, must be convertible to "Nz::String" + * + * \remark Produce a NazaraAssert if pointer to Abstracthash is invalid + * + * \see ComputeHash + */ + template ByteArray ComputeHash(AbstractHash* hash, const T& v) { + NazaraAssert(hash != nullptr, "Invalid abstracthash pointer"); + hash->Begin(); HashAppend(hash, v); @@ -62,19 +107,44 @@ namespace Nz return hash->End(); } - template + /*! + * \brief Returns the number of elements in a C-array + * \return The number of elements + * + * \param name C-array + * + * \see CountOf + */ + + template constexpr std::size_t CountOf(T(&name)[N]) noexcept { return N; } - template + /*! + * \brief Returns the number of elements in a container + * \return The number of elements + * + * \param c Container with the member function "size()" + * + * \see CountOf + */ + + template std::size_t CountOf(const T& c) { return c.size(); } - // Algorithme venant de CityHash par Google + /*! + * \brief Combines two hash in one + * + * \param seed First value that will be modified (expected to be 64bits) + * \param v Second value to hash + */ + + // Algorithm from CityHash by Google // http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co template void HashCombine(std::size_t& seed, const T& v) @@ -91,10 +161,20 @@ namespace Nz seed = static_cast(b * kMul); } - template struct PointedType {typedef T type;}; - template struct PointedType {typedef T type;}; - template struct PointedType {typedef T type;}; - template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + template struct PointedType {typedef T type;}; + + /*! + * \brief Serializes a boolean + * \return true if serialization succedeed + * + * \param context Context for the serialization + * \param value Boolean to serialize + * + * \see Serialize, Unserialize + */ inline bool Serialize(SerializationContext& context, bool value) { @@ -113,6 +193,16 @@ namespace Nz return true; } + /*! + * \brief Serializes an arithmetic type + * \return true if serialization succedeed + * + * \param context Context for the serialization + * \param value Arithmetic type to serialize + * + * \see Serialize, Unserialize + */ + template std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { @@ -131,6 +221,16 @@ namespace Nz return context.stream->Write(&value, sizeof(T)) == sizeof(T); } + /*! + * \brief Unserializes a boolean + * \return true if unserialization succedeed + * + * \param context Context for the unserialization + * \param value Pointer to boolean to unserialize + * + * \see Serialize, Unserialize + */ + inline bool Unserialize(SerializationContext& context, bool* value) { if (context.currentBitPos == 8) @@ -149,6 +249,18 @@ namespace Nz return true; } + /*! + * \brief Unserializes an arithmetic type + * \return true if unserialization succedeed + * + * \param context Context for the unserialization + * \param value Pointer to arithmetic type to serialize + * + * \remark Produce a NazaraAssert if pointer to value is invalid + * + * \see Serialize, Unserialize + */ + template std::enable_if_t::value, bool> Unserialize(SerializationContext& context, T* value) { diff --git a/tests/Engine/Core/AlgorithmCore.cpp b/tests/Engine/Core/AlgorithmCore.cpp new file mode 100644 index 000000000..8aff5cb24 --- /dev/null +++ b/tests/Engine/Core/AlgorithmCore.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include + +#include + +TEST_CASE("Apply", "[CORE][ALGORITHM]") +{ + SECTION("Apply lambda to two vector2") + { + Nz::Vector2 vector = Nz::Vector2::Unit(); + auto lambda = [](const Nz::Vector2& vec1, const Nz::Vector2& vec2) + { + return vec1 + vec2; + }; + + Nz::Vector2 result = Nz::Apply(lambda, std::make_tuple(vector, vector)); + + REQUIRE(result == (Nz::Vector2::Unit() * 2)); + } + + SECTION("Apply member function to vector2") + { + Nz::Vector2 vector = Nz::Vector2::Unit(); + + int result = Nz::Apply(vector, &Nz::Vector2::Distance, std::make_tuple(vector)); + + REQUIRE(result == 0); + } +} + +TEST_CASE("ComputeHash", "[CORE][ALGORITHM]") +{ + SECTION("Compute hash of '0'") + { + auto result = Nz::ComputeHash(Nz::HashType_SHA512, "1234"); + REQUIRE(result.ToHex().ToUpper() == "D404559F602EAB6FD602AC7680DACBFAADD13630335E951F097AF3900E9DE176B6DB28512F2E000B9D04FBA5133E8B1C6E8DF59DB3A8AB9D60BE4B97CC9E81DB"); + } +} From 5c3b16f4a7b8b685dd2caa3152be030cf018a70b Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:21:04 +0100 Subject: [PATCH 103/229] Documentation for Bitset Former-commit-id: f06a3bdb376bcfafb60d0386993806c818ca2c45 --- include/Nazara/Core/Bitset.inl | 548 +++++++++++++++++++++++++++++++-- tests/Engine/Core/Bitset.cpp | 117 +++++++ 2 files changed, 634 insertions(+), 31 deletions(-) create mode 100644 tests/Engine/Core/Bitset.cpp diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 68104b093..1b4cab200 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -16,12 +16,30 @@ namespace Nz { + /*! + * \class Nz::Bitset + * \brief Core class that represents a set of bits + * + * This class meets the requirements of Container, AllocatorAwareContainer, SequenceContainer + */ + + /*! + * \brief Constructs a Bitset object by default + */ + template Bitset::Bitset() : m_bitCount(0) { } + /*! + * \brief Constructs a Bitset object of bitCount bits to value val + * + * \param bitCount Number of bits + * \param val Value of those bits, by default false + */ + template Bitset::Bitset(unsigned int bitCount, bool val) : Bitset() @@ -29,12 +47,29 @@ namespace Nz Resize(bitCount, val); } + /*! + * \brief Constructs a Bitset object from the contents initialized with a copy of the null-terminated character string pointed to by bits + * + * \param bits Null-terminated character string containing only '0' and '1' + * + * \remark The length of the string is determined by the first null character, if there is no null character, the behaviour is undefined + */ + template Bitset::Bitset(const char* bits) : Bitset(bits, std::strlen(bits)) { } + /*! + * \brief Constructs a Bitset object from the contents initialized with a copy of the character string pointed to by bits takings the bitCount first characters + * + * \param bits Character string containing only '0' and '1' + * \param bitCount Number of characters to take into consideration + * + * \remark If the length of the string is inferior to the bitCount, the behaviour is undefined + */ + template Bitset::Bitset(const char* bits, unsigned int bitCount) : m_blocks(ComputeBlockCount(bitCount), 0U), @@ -45,12 +80,12 @@ namespace Nz switch (*bits++) { case '1': - // On adapte l'indice (inversion par rapport à la chaîne) + // We adapt the index (inversion in comparison to the string) Set(m_bitCount - i - 1, true); break; case '0': - // Tous les blocs ont été initialisés à zéro, rien à faire ici + // Each block is zero-initialised, nothing to do break; default: @@ -60,12 +95,24 @@ namespace Nz } } + /*! + * \brief Constructs a Bitset object from a Nz::String + * + * \param bits String containing only '0' and '1' + */ + template Bitset::Bitset(const String& bits) : Bitset(bits.GetConstBuffer(), bits.GetSize()) { } + /*! + * \brief Clears the content of the bitset, GetSize() is now equals to 0 + * + * \remark The memory allocated is not released + */ + template void Bitset::Clear() { @@ -73,6 +120,11 @@ namespace Nz m_blocks.clear(); } + /*! + * \brief Counts the number of bits set to 1 + * \return Number of bits set to 1 + */ + template unsigned int Bitset::Count() const { @@ -86,6 +138,10 @@ namespace Nz return count; } + /*! + * \brief Flips each bit of the bitset + */ + template void Bitset::Flip() { @@ -95,12 +151,26 @@ namespace Nz ResetExtraBits(); } + /*! + * \brief Finds the first bit set to one in the bitset + * \return Index of the first bit + */ + template unsigned int Bitset::FindFirst() const { return FindFirstFrom(0); } + /*! + * \brief Finds the next bit set to one in the bitset + * \return Index of the next bit if exists or npos + * + * \param bit Index of the bit, the search begin with bit + 1 + * + * \remark Produce a NazaraAssert if bit is greather than number of bits in bitset + */ + template unsigned int Bitset::FindNext(unsigned int bit) const { @@ -109,23 +179,32 @@ namespace Nz if (++bit >= m_bitCount) return npos; - // Le bloc du bit, l'indice du bit + // The block of the bit and its index unsigned int blockIndex = GetBlockIndex(bit); unsigned int bitIndex = GetBitIndex(bit); - // Récupération du bloc + // We get the block Block block = m_blocks[blockIndex]; - // On ignore les X premiers bits + // We ignore the X first bits block >>= bitIndex; - // Si le bloc n'est pas nul, c'est bon, sinon on doit chercher à partir du prochain bloc + // If the block is not empty, it's good, else we must keep trying with the next block if (block) return IntegralLog2Pot(block & -block) + bit; else return FindFirstFrom(blockIndex + 1); } + /*! + * \brief Gets the ith block + * \return Block in the bitset + * + * \param i Index of the block + * + * \remark Produce a NazaraAssert if i is greather than number of blocks in bitset + */ + template Block Bitset::GetBlock(unsigned int i) const { @@ -134,41 +213,71 @@ namespace Nz return m_blocks[i]; } + /*! + * \brief Gets the number of blocks + * \return Number of blocks + */ + template unsigned int Bitset::GetBlockCount() const { return m_blocks.size(); } + /*! + * \brief Gets the capacity of the bitset + * \return Capacity of the bitset + */ + template unsigned int Bitset::GetCapacity() const { return m_blocks.capacity()*bitsPerBlock; } + /*! + * \brief Gets the number of bits + * \return Number of bits + */ + template unsigned int Bitset::GetSize() const { return m_bitCount; } + /*! + * \brief Performs the "AND" operator between two bitsets + * + * \param a First bitset + * \param b Second bitset + * + * \remark The "AND" is performed with all the bits of the smallest bitset and the capacity of this is set to the largest of the two bitsets + */ + template void Bitset::PerformsAND(const Bitset& a, const Bitset& b) { std::pair minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount()); - // On réinitialise nos blocs à zéro + // We reinitialise our blocks with zero m_blocks.clear(); m_blocks.resize(minmax.second, 0U); m_bitCount = std::max(a.GetSize(), b.GetSize()); - // Dans le cas du AND, nous pouvons nous arrêter à la plus petite taille (car 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) m_blocks[i] = a.GetBlock(i) & b.GetBlock(i); ResetExtraBits(); } + /*! + * \brief Performs the "NOT" operator of the bitset + * + * \param a Bitset to negate + */ + template void Bitset::PerformsNOT(const Bitset& a) { @@ -181,6 +290,15 @@ namespace Nz ResetExtraBits(); } + /*! + * \brief Performs the "OR" operator between two bitsets + * + * \param a First bitset + * \param b Second bitset + * + * \remark The "OR" is performed with all the bits of the smallest bitset and the others are copied from the largest and the capacity of this is set to the largest of the two bitsets + */ + template void Bitset::PerformsOR(const Bitset& a, const Bitset& b) { @@ -201,6 +319,15 @@ namespace Nz ResetExtraBits(); } + /*! + * \brief Performs the "XOR" operator between two bitsets + * + * \param a First bitset + * \param b Second bitset + * + * \remark The "XOR" is performed with all the bits of the smallest bitset and the others are copied from the largest and the capacity of this is set to the largest of the two bitsets + */ + template void Bitset::PerformsXOR(const Bitset& a, const Bitset& b) { @@ -221,10 +348,16 @@ namespace Nz ResetExtraBits(); } + /*! + * \brief Checks if bitsets have one block in common + * + * \param bitset Bitset to test + */ + template bool Bitset::Intersects(const Bitset& bitset) const { - // On ne testera que les blocs en commun + // We only test the blocks in common unsigned int sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount()); for (unsigned int i = 0; i < sharedBlocks; ++i) { @@ -237,40 +370,71 @@ namespace Nz return false; } + /*! + * \brief Reserves enough blocks to contain bitCount bits + * + * \param bitCount Number of bits to reserve + */ + template void Bitset::Reserve(unsigned int bitCount) { m_blocks.reserve(ComputeBlockCount(bitCount)); } + /*! + * \brief Resizes the bitset to the size of bitCount + * + * \param bitCount Number of bits to resize + * \param defaultVal Value of the bits if new size is greather than the old one + */ + template void Bitset::Resize(unsigned int bitCount, bool defaultVal) { - // On commence par changer la taille du conteneur, avec la valeur correcte d'initialisation + // We begin with changing the size of container, with the correct value of initialisation unsigned int lastBlockIndex = m_blocks.size() - 1; m_blocks.resize(ComputeBlockCount(bitCount), (defaultVal) ? fullBitMask : 0U); unsigned int remainingBits = GetBitIndex(m_bitCount); if (bitCount > m_bitCount && remainingBits > 0 && defaultVal) - // Initialisation des bits non-utilisés du dernier bloc avant le changement de taille + // Initialisation of unused bits in the last block before the size change m_blocks[lastBlockIndex] |= fullBitMask << remainingBits; m_bitCount = bitCount; ResetExtraBits(); } + /*! + * \brief Resets the bitset to zero bits + */ + template void Bitset::Reset() { Set(false); } + /*! + * \brief Resets the bit at the index + * + * \param bit Index of the bit + * + * \see UnboundReset + */ + template void Bitset::Reset(unsigned int bit) { Set(bit, false); } + /*! + * \brief Sets the bitset to val + * + * \param val Value of the bits + */ + template void Bitset::Set(bool val) { @@ -279,6 +443,17 @@ namespace Nz ResetExtraBits(); } + /*! + * \brief Sets the bit at the index + * + * \param bit Index of the bit + * \param val Value of the bit + * + * \remark Produce a NazaraAssert if bit is greather than number of bits in bitset + * + * \see UnboundSet + */ + template void Bitset::Set(unsigned int bit, bool val) { @@ -287,11 +462,19 @@ namespace Nz Block& block = m_blocks[GetBlockIndex(bit)]; Block mask = Block(1U) << GetBitIndex(bit); - // Activation du bit sans branching + // Activation of the bit without branching // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching block = (block & ~mask) | (-val & mask); } + /*! + * \brief Set the ith block + * + * \param i Index of the block + * \param block Block to set + * + * \remark Produce a NazaraAssert if i is greather than number of blocks in bitset + */ template void Bitset::SetBlock(unsigned int i, Block block) { @@ -302,6 +485,12 @@ namespace Nz ResetExtraBits(); } + /*! + * \brief Swaps the two bitsets + * + * \param bitset Other bitset to swap + */ + template void Bitset::Swap(Bitset& bitset) { @@ -309,6 +498,17 @@ namespace Nz std::swap(m_blocks, bitset.m_blocks); } + /*! + * \brief Tests the ith bit + * \return true if bit is set + * + * \param bit Index of the bit + * + * \remark Produce a NazaraAssert if bit is greather than number of bits in bitset + * + * \see UnboundTest + */ + template bool Bitset::Test(unsigned int bit) const { @@ -317,22 +517,32 @@ namespace Nz return (m_blocks[GetBlockIndex(bit)] & (Block(1U) << GetBitIndex(bit))) != 0; } + /*! + * \brief Tests each block + * \return true if each block is set + */ + template bool Bitset::TestAll() const { - // Cas particulier du dernier bloc + // Special case for the last block Block lastBlockMask = GetLastBlockMask(); for (unsigned int i = 0; i < m_blocks.size(); ++i) { Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; - if (m_blocks[i] == mask) // Les extra bits sont à zéro, on peut donc tester sans procéder à un masquage + if (m_blocks[i] == mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask return false; } return true; } + /*! + * \brief Tests if one bit is set + * \return true if one bit is set + */ + template bool Bitset::TestAny() const { @@ -348,12 +558,24 @@ namespace Nz return false; } + /*! + * \brief Tests if one bit is not set + * \return true if one bit is not set + */ + template bool Bitset::TestNone() const { return !TestAny(); } + /*! + * \brief Converts the bitset to template type + * \return The conversion of the bitset + * + * \remark Produce a NazaraAssert if the template type can not hold the number of bits + */ + template template T Bitset::To() const @@ -369,6 +591,11 @@ namespace Nz return value; } + /*! + * \brief Gives a string representation + * \return A string representation of the object with only '0' and '1' + */ + template String Bitset::ToString() const { @@ -383,12 +610,33 @@ namespace Nz return str; } + /*! + * \brief Resets the bit at the index + * + * \param bit Index of the bit + * + * \remark if bit is greather than the number of bits, the bitset is enlarged and the added bits are set to false + * + * \see Reset + */ + template void Bitset::UnboundedReset(unsigned int bit) { UnboundedSet(bit, false); } + /*! + * \brief Sets the bit at the index + * + * \param bit Index of the bit + * \param val Value of the bit + * + * \remark if bit is greather than the number of bits, the bitset is enlarged and the added bits are set to false and the one at bit is set to val + * + * \see Set + */ + template void Bitset::UnboundedSet(unsigned int bit, bool val) { @@ -402,6 +650,15 @@ namespace Nz } } + /*! + * \brief Tests the ith bit + * \return true if bit is set + * + * \param bit Index of the bit + * + * \see Test + */ + template bool Bitset::UnboundedTest(unsigned int bit) const { @@ -411,18 +668,33 @@ namespace Nz return false; } + /*! + * \brief Gets the ith bit + * \return bit in ith position + */ + template typename Bitset::Bit Bitset::operator[](int index) { return Bit(m_blocks[GetBlockIndex(index)], Block(1U) << GetBitIndex(index)); } + /*! + * \brief Gets the ith bit + * \return bit in ith position + */ + template bool Bitset::operator[](int index) const { return Test(index); } + /*! + * \brief Negates the bitset + * \return A new bitset which is the "NOT" of this bitset + */ + template Bitset Bitset::operator~() const { @@ -432,6 +704,13 @@ namespace Nz return bitset; } + /*! + * \brief Sets this bitset from a Nz::String + * \return A reference to this + * + * \param bits String containing only '0' and '1' + */ + template Bitset& Bitset::operator=(const String& bits) { @@ -441,6 +720,13 @@ namespace Nz return *this; } + /*! + * \brief Performs an "AND" with another bitset + * \return A reference to this + * + * \param bitset Other bitset + */ + template Bitset& Bitset::operator&=(const Bitset& bitset) { @@ -449,6 +735,13 @@ namespace Nz return *this; } + /*! + * \brief Performs an "OR" with another bitset + * \return A reference to this + * + * \param bitset Other bitset + */ + template Bitset& Bitset::operator|=(const Bitset& bitset) { @@ -457,6 +750,13 @@ namespace Nz return *this; } + /*! + * \brief Performs an "XOR" with another bitset + * \return A reference to this + * + * \param bitset Other bitset + */ + template Bitset& Bitset::operator^=(const Bitset& bitset) { @@ -465,13 +765,20 @@ namespace Nz return *this; } + /*! + * \brief Finds the position of the first bit set to true after the blockIndex + * \return The position of the bit + * + * \param blockIndex Index of the block + */ + template unsigned int Bitset::FindFirstFrom(unsigned int blockIndex) const { if (blockIndex >= m_blocks.size()) return npos; - // On cherche le premier bloc non-nul + // We are looking for the first non-null block unsigned int i = blockIndex; for (; i < m_blocks.size(); ++i) { @@ -479,22 +786,31 @@ namespace Nz break; } - // Est-ce qu'on a un bloc non-nul ? + // Do we have a non-null block ? if (i == m_blocks.size()) return npos; Block block = m_blocks[i]; - // Calcul de la position du LSB dans le bloc (et ajustement de la position) + // Compute the position of LSB in the block (and adjustement of the position) return IntegralLog2Pot(block & -block) + i*bitsPerBlock; } + /*! + * \brief Gets the mask associated to the last block + * \return Block which represents the mask + */ + template Block Bitset::GetLastBlockMask() const { return (Block(1U) << GetBitIndex(m_bitCount)) - 1U; } + /*! + * \brief Sets to '0' the last bits unassigned in the last block + */ + template void Bitset::ResetExtraBits() { @@ -503,24 +819,43 @@ namespace Nz m_blocks.back() &= mask; } + /*! + * \brief Computes the block count with the index of the bit + * \return Number of the blocks to contain the bit + */ + template unsigned int Bitset::ComputeBlockCount(unsigned int bitCount) { return GetBlockIndex(bitCount) + ((GetBitIndex(bitCount) != 0U) ? 1U : 0U); } + /*! + * \brief Computes the bit position in the block + * \return Index of the bit in the block + */ + template unsigned int Bitset::GetBitIndex(unsigned int bit) { return bit & (bitsPerBlock - 1U); // bit % bitsPerBlock } + /*! + * \brief Computes the block index with the index of the bit + * \return Index of the block containing the bit + */ + template unsigned int Bitset::GetBlockIndex(unsigned int bit) { return bit / bitsPerBlock; } + /*! + * \brief Flips the bit + * \return A reference to this + */ template typename Bitset::Bit& Bitset::Bit::Flip() @@ -530,12 +865,24 @@ namespace Nz return *this; } + /*! + * \brief Resets the bit + * \return A reference to this + */ + template typename Bitset::Bit& Bitset::Bit::Reset() { return Set(false); } + /*! + * \brief Sets the bit to a value + * \return A reference to this + * + * \param val Value of the bit + */ + template typename Bitset::Bit& Bitset::Bit::Set(bool val) { @@ -545,47 +892,85 @@ namespace Nz return *this; } + /*! + * \brief Tests the bit + * \return A reference to this + */ + template bool Bitset::Bit::Test() const { return m_block & m_mask; } + /*! + * \brief Gets the adress of the bit + * \return Nullptr + * + * \see std::addressof + */ + template template void* Bitset::Bit::operator&() const { - // Le template est nécessaire pour ne planter la compilation qu'à l'utilisation + // The template is necessary to make it fail only when used static_assert(!BadCall, "It is impossible to take the address of a bit in a bitset"); return nullptr; } + /*! + * \brief Converts this to bool + * \return true if bit set to '1' + */ + template Bitset::Bit::operator bool() const { return Test(); } + /*! + * \brief Sets the bit to a value + * \return A reference to this + * + * \param val Value of the bit + */ + template typename Bitset::Bit& Bitset::Bit::operator=(bool val) { return Set(val); } + /*! + * \brief Sets the bit to the value of another one + * \return A reference to this + * + * \param bit Other bit + */ + template typename Bitset::Bit& Bitset::Bit::operator=(const Bit& bit) { return Set(bit); } + /*! + * \brief Performs the operator "OR" on this bit with a boolean + * \return A reference to this + * + * \param val Value + */ + template typename Bitset::Bit& Bitset::Bit::operator|=(bool val) { - // Version sans branching: + // Version without branching: Set((val) ? true : Test()); - // Avec branching: + // With branching: /* if (val) Set(); @@ -594,13 +979,20 @@ namespace Nz return *this; } + /*! + * \brief Performs the operator "AND" on this bit with a boolean + * \return A reference to this + * + * \param val Value + */ + template typename Bitset::Bit& Bitset::Bit::operator&=(bool val) { - // Version sans branching: + // Version without branching: Set((val) ? Test() : false); - // Avec branching: + // With branching: /* if (!val) Reset(); @@ -609,13 +1001,20 @@ namespace Nz return *this; } + /*! + * \brief Performs the operator "XOR" on this bit with a boolean + * \return A reference to this + * + * \param val Value + */ + template typename Bitset::Bit& Bitset::Bit::operator^=(bool val) { - // Version sans branching: + // Version without branching: Set((val) ? !Test() : Test()); - // Avec branching: + // With branching: /* if (val) Flip(); @@ -624,13 +1023,20 @@ namespace Nz return *this; } + /*! + * \brief Performs the operator "RESET" on this bit with a boolean + * \return A reference to this + * + * \param val Value + */ + template typename Bitset::Bit& Bitset::Bit::operator-=(bool val) { - // Version sans branching: + // Version without branching: Set((val) ? false : Test()); - // Avec branching: + // With branching: /* if (val) Reset(); @@ -639,26 +1045,35 @@ namespace Nz return *this; } + /*! + * \brief Compares two bitsets + * \return true if the two bitsets are the same + * + * \param lhs First bitset to compare with + * \param rhs Other bitset to compare with + * + * \remark If one is bigger, they are equal only if the largest has the last bit set to '0' + */ + template bool operator==(const Bitset& lhs, const Bitset& rhs) { - // La comparaison part du principe que (uint8) 00001100 == (uint16) 00000000 00001100 - // et conserve donc cette propriété + // The comparison uses that (uint8) 00001100 == (uint16) 00000000 00001100 + // and thus conserve this property const Bitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; const Bitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; unsigned int maxBlockCount = greater.GetBlockCount(); unsigned int minBlockCount = lesser.GetBlockCount(); - // Nous testons les blocs en commun pour vérifier l'égalité des bits + // We test the blocks in common to check the equality of bits for (unsigned int i = 0; i < minBlockCount; ++i) { if (lhs.GetBlock(i) != rhs.GetBlock(i)) return false; } - // Nous vérifions maintenant les blocs que seul le plus grand bitset possède, pour prétendre à l'égalité - // ils doivent tous être nuls + // 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) if (greater.GetBlock(i)) return false; @@ -666,12 +1081,28 @@ namespace Nz return true; } + /*! + * \brief Compares two bitsets + * \return false if the two bitsets are the same + * + * \param lhs First bitset to compare with + * \param rhs Other bitset to compare with + */ + template bool operator!=(const Bitset& lhs, const Bitset& rhs) { return !(lhs == rhs); } + /*! + * \brief Compares two bitsets + * \return true if the binary number represented by the lhs bitset is smaller + * + * \param lhs First bitset to compare with + * \param rhs Other bitset to compare with + */ + template bool operator<(const Bitset& lhs, const Bitset& rhs) { @@ -699,24 +1130,56 @@ namespace Nz return false; // They are equal } + /*! + * \brief Compares two bitsets + * \return true if the binary number represented by the lhs bitset is smaller or equal + * + * \param lhs First bitset to compare with + * \param rhs Other bitset to compare with + */ + template bool operator<=(const Bitset& lhs, const Bitset& rhs) { return lhs < rhs || lhs == rhs; } + /*! + * \brief Compares two bitsets + * \return true if the binary number represented by the lhs bitset is greather + * + * \param lhs First bitset to compare with + * \param rhs Other bitset to compare with + */ + template bool operator>(const Bitset& lhs, const Bitset& rhs) { return rhs < lhs; } + /*! + * \brief Compares two bitsets + * \return true if the binary number represented by the lhs bitset is greather or equal + * + * \param lhs First bitset to compare with + * \param rhs Other bitset to compare with + */ + template bool operator>=(const Bitset& lhs, const Bitset& rhs) { return rhs <= lhs; } + /*! + * \brief Performs the operator "AND" between two bitsets + * \return The result of operator "AND" + * + * \param lhs First bitset + * \param rhs Second bitset + */ + template Bitset operator&(const Bitset& lhs, const Bitset& rhs) { @@ -726,6 +1189,14 @@ namespace Nz return bitset; } + /*! + * \brief Performs the operator "OR" between two bitsets + * \return The result of operator "OR" + * + * \param lhs First bitset + * \param rhs Second bitset + */ + template Bitset operator|(const Bitset& lhs, const Bitset& rhs) { @@ -735,6 +1206,14 @@ namespace Nz return bitset; } + /*! + * \brief Performs the operator "XOR" between two bitsets + * \return The result of operator "XOR" + * + * \param lhs First bitset + * \param rhs Second bitset + */ + template Bitset operator^(const Bitset& lhs, const Bitset& rhs) { @@ -748,6 +1227,13 @@ namespace Nz namespace std { + /*! + * \brief Swaps two bitsets, specialisation of std + * + * \param lhs First bitset + * \param rhs Second bitset + */ + template void swap(Nz::Bitset& lhs, Nz::Bitset& rhs) { diff --git a/tests/Engine/Core/Bitset.cpp b/tests/Engine/Core/Bitset.cpp new file mode 100644 index 000000000..76c35c886 --- /dev/null +++ b/tests/Engine/Core/Bitset.cpp @@ -0,0 +1,117 @@ +#include +#include + +#include + +SCENARIO("Bitset", "[CORE][BITSET]") +{ + GIVEN("Allocate and constructor") + { + Nz::Bitset<> bitset(3); + + THEN("Capacity is 3 and size is 3") + { + REQUIRE(bitset.GetSize() == 3); + REQUIRE(bitset.GetCapacity() >= 3); + } + } + + GIVEN("Iterator and default constructor") + { + Nz::String anotherDataString("0101"); + Nz::Bitset<> defaultByte; + Nz::Bitset<> anotherData(anotherDataString.GetConstBuffer()); + + WHEN("We assign 'anotherData'") + { + defaultByte = anotherDataString; + REQUIRE(anotherData == defaultByte); + REQUIRE(defaultByte.GetSize() == 4); + REQUIRE(defaultByte.GetCapacity() >= 4); + REQUIRE(anotherData.GetSize() == 4); + REQUIRE(anotherData.GetCapacity() >= 4); + } + } + + GIVEN("Copy and Move constructor") + { + Nz::Bitset<> originalArray(3, true); + + WHEN("We copy") + { + Nz::Bitset<> copyBitset(originalArray); + + THEN("We get a copy") + { + REQUIRE(copyBitset == originalArray); + + AND_WHEN("We modify one") + { + for (auto i = 0; i < copyBitset.GetSize(); ++i) + copyBitset[i] = false; + + THEN("They are no more equal") + { + REQUIRE(copyBitset != originalArray); + REQUIRE(copyBitset == Nz::Bitset<>(3, false)); + } + } + } + } + + WHEN("We move") + { + Nz::Bitset<> moveBitset(std::move(originalArray)); + + THEN("These results are expected") + { + REQUIRE(moveBitset == Nz::Bitset<>(3, true)); + REQUIRE(originalArray.GetCapacity() == 0); + } + } + } + + GIVEN("Three bitsets") + { + Nz::Bitset<> first("01001"); + Nz::Bitset<> second("10110"); + Nz::Bitset<> third; + + WHEN("We swap first and third, then second and third and finally third and first") + { + Nz::Bitset<> oldFirst(first); + Nz::Bitset<> oldSecond(second); + + first.Swap(third); + std::swap(second, third); + third.Swap(first); + + THEN("First and second have been swapped and third is still empty.") + { + REQUIRE(oldFirst == second); + REQUIRE(oldSecond == first); + REQUIRE(third.GetSize() == 0); + } + } + } + + GIVEN("Two bitsets") + { + Nz::Bitset<> first("01001"); + Nz::Bitset<> second("10111"); + + WHEN("We perform operators") + { + Nz::Bitset<> andBitset = first & second; + Nz::Bitset<> orBitset = first | second; + Nz::Bitset<> xorBitset = first ^ second; + + THEN("They should operate as logical operators") + { + REQUIRE(andBitset == Nz::Bitset<>("00001")); + REQUIRE(orBitset == Nz::Bitset<>("11111")); + REQUIRE(xorBitset == Nz::Bitset<>("11110")); + } + } + } +} From de5a994a5c24c05be4d095ed3efb5ce314f8c972 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:21:56 +0100 Subject: [PATCH 104/229] Documentation for MemoryPool Former-commit-id: 8464b058829189b16cc2336de6454a38f9ee3bdf --- include/Nazara/Core/MemoryPool.hpp | 2 +- include/Nazara/Core/MemoryPool.inl | 94 +++++++++++++++++++++++++++--- tests/Engine/Core/MemoryPool.cpp | 28 +++++++++ 3 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 tests/Engine/Core/MemoryPool.cpp diff --git a/include/Nazara/Core/MemoryPool.hpp b/include/Nazara/Core/MemoryPool.hpp index 71761b612..7aaa462bb 100644 --- a/include/Nazara/Core/MemoryPool.hpp +++ b/include/Nazara/Core/MemoryPool.hpp @@ -37,7 +37,7 @@ namespace Nz private: MemoryPool(MemoryPool* pool); - std::unique_ptr m_freeList; + std::unique_ptr m_freeList; std::unique_ptr m_pool; std::unique_ptr m_next; std::atomic_uint m_freeCount; diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 9ba21fa0c..1f3993974 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -8,6 +8,19 @@ namespace Nz { + /*! + * \class Nz::MemoryPool + * \brief Core class that represents a memory pool + */ + + /*! + * \brief Constructs a MemoryPool object + * + * \param blockSize Size of blocks that will be allocated + * \param size Size of the pool + * \param canGrow Determine if the pool can allocate more memory + */ + inline MemoryPool::MemoryPool(unsigned int blockSize, unsigned int size, bool canGrow) : m_freeCount(size), m_previous(nullptr), @@ -16,27 +29,47 @@ namespace Nz m_size(size) { m_pool.reset(new UInt8[blockSize * size]); - m_freeList.reset(new void*[size]); + m_freeList.reset(new void* [size]); // Remplissage de la free list for (unsigned int i = 0; i < size; ++i) m_freeList[i] = &m_pool[m_blockSize * (size-i-1)]; } + /*! + * \brief Constructs a MemoryPool object by move semantic + * + * \param pool MemoryPool to move into this + */ + inline MemoryPool::MemoryPool(MemoryPool&& pool) noexcept { operator=(std::move(pool)); } + /*! + * \brief Constructs a MemoryPool object by chaining memory pool + * + * \param pool Previous MemoryPool + */ + inline MemoryPool::MemoryPool(MemoryPool* pool) : MemoryPool(pool->m_blockSize, pool->m_size, pool->m_canGrow) { m_previous = pool; } + /*! + * \brief Allocates enough memory for the size and returns a pointer to it + * \return A pointer to memory allocated + * + * \param size Size to allocate + * + * \remark If the size is greather than the blockSize of pool, new operator is called + */ + inline void* MemoryPool::Allocate(unsigned int size) { - ///DOC: Si la taille est supérieure à celle d'un bloc du pool, l'opérateur new est utilisé if (size <= m_blockSize) { if (m_freeCount > 0) @@ -53,10 +86,17 @@ namespace Nz return OperatorNew(size); } + /*! + * \brief Deletes the memory represented by the poiner + * + * Calls the destructor of the object before releasing it + * + * \remark If ptr is null, nothing is done + */ + template inline void MemoryPool::Delete(T* ptr) { - ///DOC: Va appeler le destructeur de l'objet avant de le libérer if (ptr) { ptr->~T(); @@ -64,12 +104,20 @@ namespace Nz } } + /*! + * \brief Frees the memory represented by the poiner + * + * If the pool gets empty after the call and we are the child of another pool, we commit suicide. If the pointer does not own to a block of the pool, operator delete is called + * + * \remark Throws a std::runtime_error if pointer does not point to an element of the pool with NAZARA_CORE_SAFE defined + * \remark If ptr is null, nothing is done + */ + inline void MemoryPool::Free(void* ptr) { - ///DOC: Si appelé avec un pointeur ne faisant pas partie du pool, l'opérateur delete est utilisé if (ptr) { - // Le pointeur nous appartient-il ? + // Does the pointer belong to us ? UInt8* freePtr = static_cast(ptr); UInt8* poolPtr = m_pool.get(); if (freePtr >= poolPtr && freePtr < poolPtr + m_blockSize*m_size) @@ -81,7 +129,7 @@ namespace Nz m_freeList[m_freeCount++] = ptr; - // Si nous sommes vide et l'extension d'un autre pool, nous nous suicidons + // If we are empty and the extension of another pool, we commit suicide if (m_freeCount == m_size && m_previous && !m_next) { m_previous->m_next.release(); @@ -98,31 +146,61 @@ namespace Nz } } + /*! + * \brief Gets the block size + * \return Size of the blocks + */ + inline unsigned int MemoryPool::GetBlockSize() const { return m_blockSize; } + /*! + * \brief Gets the number of free blocks + * \return Number of free blocks in the pool + */ + inline unsigned int MemoryPool::GetFreeBlocks() const { return m_freeCount; } + /*! + * \brief Gets the pool size + * \return Size of the pool + */ + inline unsigned int MemoryPool::GetSize() const { return m_size; } + /*! + * \brief Creates a new value of type T with arguments + * \return Pointer to the allocated object + * + * \param args Arguments for the new object + * + * \remark Constructs inplace in the pool + */ + template inline T* MemoryPool::New(Args&&... args) { - ///DOC: Permet de construire un objet directement dans le pook T* object = static_cast(Allocate(sizeof(T))); PlacementNew(object, std::forward(args)...); return object; } + /*! + * \brief Assigns the content of another pool by move semantic + * \return A reference to this + * + * \param pool Other pool to move into this + */ + inline MemoryPool& MemoryPool::operator=(MemoryPool&& pool) noexcept { m_blockSize = pool.m_blockSize; @@ -134,7 +212,7 @@ namespace Nz m_next = std::move(pool.m_next); m_size = pool.m_size; - // Si nous avons été créés par un autre pool, nous devons le faire pointer vers nous de nouveau + // If we have been created by another pool, we must make it point to us again if (m_previous) { m_previous->m_next.release(); diff --git a/tests/Engine/Core/MemoryPool.cpp b/tests/Engine/Core/MemoryPool.cpp new file mode 100644 index 000000000..6a3c230c4 --- /dev/null +++ b/tests/Engine/Core/MemoryPool.cpp @@ -0,0 +1,28 @@ +#include +#include + +#include + +SCENARIO("MemoryPool", "[CORE][MEMORYPOOL]") +{ + GIVEN("A MemoryPool to contain one Nz::Vector2") + { + Nz::MemoryPool memoryPool(sizeof(Nz::Vector2), 1, false); + + WHEN("We construct a Nz::Vector2") + { + Nz::Vector2* vector2 = memoryPool.New>(1, 2); + + THEN("Memory is available") + { + vector2->x = 3; + REQUIRE(*vector2 == Nz::Vector2(3, 2)); + } + + THEN("We can destroy the vector2") + { + memoryPool.Delete(vector2); + } + } + } +} From 040c8b099ff1ab190123199435487ea4bad0aab8 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:22:57 +0100 Subject: [PATCH 105/229] Documentation for ObjectRef Former-commit-id: 3c704ed4e8999b0cdc66f6fe29ca0f170cc6619c --- include/Nazara/Core/ObjectRef.inl | 121 +++++++++++++++++++++++++++++- tests/Engine/Core/ObjectRef.cpp | 41 ++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 tests/Engine/Core/ObjectRef.cpp diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index 1337f0c39..7799b6cbd 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -7,12 +7,27 @@ namespace Nz { + /*! + * \class Nz::ObjectRef + * \brief Core class that represents a reference to an object + */ + + /*! + * \brief Constructs a ObjectRef object by default + */ + template ObjectRef::ObjectRef() : m_object(nullptr) { } + /*! + * \brief Constructs a ObjectRef object with a pointer to an object + * + * \param object Pointer to handle like a reference (can be nullptr) + */ + template ObjectRef::ObjectRef(T* object) : m_object(object) @@ -21,6 +36,12 @@ namespace Nz m_object->AddReference(); } + /*! + * \brief Constructs a ObjectRef object by assignation + * + * \param ref ObjectRef to assign into this + */ + template ObjectRef::ObjectRef(const ObjectRef& ref) : m_object(ref.m_object) @@ -29,6 +50,12 @@ namespace Nz m_object->AddReference(); } + /*! + * \brief Constructs a ObjectRef object from another type of ObjectRef + * + * \param ref ObjectRef of type U to convert to type T + */ + template template ObjectRef::ObjectRef(const ObjectRef& ref) : @@ -36,13 +63,23 @@ namespace Nz { } + /*! + * \brief Constructs a ObjectRef object by move semantic + * + * \param ref ObjectRef to move into this + */ + template ObjectRef::ObjectRef(ObjectRef&& ref) noexcept : m_object(ref.m_object) { - ref.m_object = nullptr; // On vole la référence + ref.m_object = nullptr; // We steal the reference } + /*! + * \brief Destructs the object (remove a reference to the object when shared) + */ + template ObjectRef::~ObjectRef() { @@ -50,27 +87,50 @@ namespace Nz m_object->RemoveReference(); } + /*! + * \brief Gets the underlying pointer + * \return Underlying pointer + */ + template T* ObjectRef::Get() const { return m_object; } + /*! + * \brief Checks whether the reference is valid + * \return true if reference is not nullptr + */ + template bool ObjectRef::IsValid() const { return m_object != nullptr; } + /*! + * \brief Releases the handle of the pointer + * \return Underlying pointer + */ + template T* ObjectRef::Release() { + if (m_object) + m_object->RemoveReference(); + T* object = m_object; m_object = nullptr; return object; } + /*! + * \brief Resets the content of the ObjectRef with another pointer + * \return true if old handle is destroyed + */ + template bool ObjectRef::Reset(T* object) { @@ -88,6 +148,13 @@ namespace Nz return destroyed; } + /*! + * \brief Swaps the content of the two ObjectRef + * \return A reference to this + * + * \param ref ObjectRef to swap + */ + template ObjectRef& ObjectRef::Swap(ObjectRef& ref) { @@ -96,24 +163,48 @@ namespace Nz return *this; } + /*! + * \brief Converts the ObjectRef to bool + * \return true if reference is not nullptr + * + * \see IsValid + */ + template ObjectRef::operator bool() const { return IsValid(); } + /*! + * \brief Dereferences the ObjectRef + * \return Underlying pointer + */ + template ObjectRef::operator T*() const { return m_object; } + /*! + * \brief Dereferences the ObjectRef + * \return Underlying pointer + */ + template T* ObjectRef::operator->() const { return m_object; } + /*! + * \brief Assigns the object into this + * \return A reference to this + * + * \param object Pointer to handle like a reference (can be nullptr) + */ + template ObjectRef& ObjectRef::operator=(T* object) { @@ -122,6 +213,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the reference of the ObjectRef with the handle from another + * \return A reference to this + * + * \param ref The other ObjectRef + */ + template ObjectRef& ObjectRef::operator=(const ObjectRef& ref) { @@ -130,6 +228,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the reference of the ObjectRef from another type of ObjectRef + * \return A reference to this + * + * \param ref ObjectRef of type U to convert + */ + template template ObjectRef& ObjectRef::operator=(const ObjectRef& ref) @@ -141,6 +246,13 @@ namespace Nz return *this; } + /*! + * \brief Moves the ObjectRef into this + * \return A reference to this + * + * \param ref ObjectRef to move in this + */ + template ObjectRef& ObjectRef::operator=(ObjectRef&& ref) noexcept { @@ -154,6 +266,13 @@ namespace Nz namespace std { + /*! + * \brief Gives a hash representation of the object, specialisation of std + * \return Hash of the ObjectRef + * + * \param object Object to hash + */ + template struct hash> { diff --git a/tests/Engine/Core/ObjectRef.cpp b/tests/Engine/Core/ObjectRef.cpp new file mode 100644 index 000000000..e44e5f1ff --- /dev/null +++ b/tests/Engine/Core/ObjectRef.cpp @@ -0,0 +1,41 @@ +#include +#include + +#include + +SCENARIO("ObjectRef", "[CORE][OBJECTREF]") +{ + GIVEN("A ObjectRef") + { + Nz::ObjectRef objectRef; + + WHEN("We have two objectRef handling the same object") + { + Nz::Font font; + + objectRef = &font; + Nz::ObjectRef otherRef(&font); + + THEN("Pointers the same") + { + REQUIRE(objectRef.IsValid()); + REQUIRE(otherRef.IsValid()); + } + + objectRef.Reset(nullptr); + } + + WHEN("We assign it to a simple font") + { + Nz::Font font; + + THEN("Release suppress the reference to the object") + { + objectRef.Reset(&font); + objectRef.Release(); + + REQUIRE(!objectRef.IsValid()); + } + } + } +} From 01d5f18d27cc35de26b6bb3a5bd78a58a45a2f5e Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:23:46 +0100 Subject: [PATCH 106/229] Documentation for ParameterList Former-commit-id: 5b8752a1d20eb894e17b271a019c379d867a4eb5 --- src/Nazara/Core/ParameterList.cpp | 261 ++++++++++++++++++++++++---- tests/Engine/Core/ParameterList.cpp | 52 ++++++ 2 files changed, 282 insertions(+), 31 deletions(-) create mode 100644 tests/Engine/Core/ParameterList.cpp diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 5b63218af..1244b8b2c 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -12,16 +12,33 @@ namespace Nz { + /*! + * \class Nz::ParameterList + * \brief Core class that represents a list of parameters + */ + + /*! + * \brief Constructs a ParameterList object by copy + */ + ParameterList::ParameterList(const ParameterList& list) { operator=(list); } + /*! + * \brief Destructs the object and clears + */ + ParameterList::~ParameterList() { Clear(); } + /*! + * \brief Clears the list of parameters + */ + void ParameterList::Clear() { for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it) @@ -30,8 +47,22 @@ namespace Nz m_parameters.clear(); } + /*! + * \brief Gets the boolean parameter by name + * \return true if success + * + * \param name Name of the variable + * \param value Value to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetBooleanParameter(const String& name, bool* value) const { + NazaraAssert(value, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -50,16 +81,16 @@ namespace Nz return true; case ParameterType_String: - { - bool converted; - if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) { - *value = converted; - return true; - } + bool converted; + if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) + { + *value = converted; + return true; + } - break; - } + break; + } case ParameterType_Float: case ParameterType_None: @@ -72,8 +103,22 @@ namespace Nz return false; } + /*! + * \brief Gets the float parameter by name + * \return true if success + * + * \param name Name of the variable + * \param value Value to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetFloatParameter(const String& name, float* value) const { + NazaraAssert(value, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -92,16 +137,16 @@ namespace Nz return true; case ParameterType_String: - { - double converted; - if (it->second.value.stringVal.ToDouble(&converted)) { - *value = static_cast(converted); - return true; - } + double converted; + if (it->second.value.stringVal.ToDouble(&converted)) + { + *value = static_cast(converted); + return true; + } - break; - } + break; + } case ParameterType_Boolean: case ParameterType_None: @@ -114,8 +159,22 @@ namespace Nz return false; } + /*! + * \brief Gets the integer parameter by name + * \return true if success + * + * \param name Name of the variable + * \param value Value to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetIntegerParameter(const String& name, int* value) const { + NazaraAssert(value, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -138,18 +197,18 @@ namespace Nz return false; case ParameterType_String: - { - long long converted; - if (it->second.value.stringVal.ToInteger(&converted)) { - if (converted <= std::numeric_limits::max() && converted >= std::numeric_limits::min()) + long long converted; + if (it->second.value.stringVal.ToInteger(&converted)) { - *value = static_cast(converted); - return true; + if (converted <= std::numeric_limits::max() && converted >= std::numeric_limits::min()) + { + *value = static_cast(converted); + return true; + } } + break; } - break; - } case ParameterType_None: case ParameterType_Pointer: @@ -161,8 +220,22 @@ namespace Nz return false; } + /*! + * \brief Gets the parameter by name + * \return true if success + * + * \param name Name of the variable + * \param type Type to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetParameterType(const String& name, ParameterType* type) const { + NazaraAssert(type, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) return false; @@ -172,8 +245,22 @@ namespace Nz return true; } + /*! + * \brief Gets the pointer parameter by name + * \return true if success + * + * \param name Name of the variable + * \param value Value to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetPointerParameter(const String& name, void** value) const { + NazaraAssert(value, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -203,8 +290,22 @@ namespace Nz return false; } + /*! + * \brief Gets the string parameter by name + * \return true if success + * + * \param name Name of the variable + * \param value Value to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetStringParameter(const String& name, String* value) const { + NazaraAssert(value, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -247,8 +348,22 @@ namespace Nz return false; } + /*! + * \brief Gets the user parameter by name + * \return true if success + * + * \param name Name of the variable + * \param value Value to set + * + * \remark Produces a NazaraAssert if pointer is invalid + * \remark Produces a NazaraError if name is not a variable + * \remark Produces a NazaraError if value could not be convertible + */ + bool ParameterList::GetUserdataParameter(const String& name, void** value) const { + NazaraAssert(value, "Invalid pointer"); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -268,11 +383,26 @@ namespace Nz } } + /*! + * \brief Checks whether the parameter list has a parameter with that name + * \return true if found + * + * \param name Name of the parameter + */ + bool ParameterList::HasParameter(const String& name) const { return m_parameters.find(name) != m_parameters.end(); } + /*! + * \brief Removes the parameter with that name + * + * Removes the parameter with that name, if not found, nothing is done + * + * \param name Name of the parameter + */ + void ParameterList::RemoveParameter(const String& name) { auto it = m_parameters.find(name); @@ -283,6 +413,12 @@ namespace Nz } } + /*! + * \brief Sets the parameter with the name to ParameterType_None + * + * \param name Name of the parameter + */ + void ParameterList::SetParameter(const String& name) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -294,6 +430,13 @@ namespace Nz parameter.type = ParameterType_None; } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + */ + void ParameterList::SetParameter(const String& name, const String& value) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -307,6 +450,13 @@ namespace Nz PlacementNew(¶meter.value.stringVal, value); } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + */ + void ParameterList::SetParameter(const String& name, const char* value) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -320,6 +470,13 @@ namespace Nz PlacementNew(¶meter.value.stringVal, value); } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + */ + void ParameterList::SetParameter(const String& name, void* value) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -332,6 +489,14 @@ namespace Nz parameter.value.ptrVal = value; } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + * \param destructor Destructor for dynamic variable + */ + void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -344,6 +509,13 @@ namespace Nz parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + */ + void ParameterList::SetParameter(const String& name, bool value) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -356,6 +528,13 @@ namespace Nz parameter.value.boolVal = value; } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + */ + void ParameterList::SetParameter(const String& name, float value) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -368,6 +547,13 @@ namespace Nz parameter.value.floatVal = value; } + /*! + * \brief Sets the parameter with the name to the value + * + * \param name Name of the parameter + * \param value Value of the parameter + */ + void ParameterList::SetParameter(const String& name, int value) { std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); @@ -380,6 +566,13 @@ namespace Nz parameter.value.intVal = value; } + /*! + * \brief Assigns the content of the other parameter list to this + * \return A reference to this + * + * \param list List to assign + */ + ParameterList& ParameterList::operator=(const ParameterList& list) { Clear(); @@ -418,6 +611,12 @@ namespace Nz return *this; } + /*! + * \brief Destroys the value for the parameter + * + * \param parameter Parameter to destroy + */ + void ParameterList::DestroyValue(Parameter& parameter) { switch (parameter.type) @@ -427,15 +626,15 @@ namespace Nz break; case ParameterType_Userdata: - { - Parameter::UserdataValue* userdata = parameter.value.userdataVal; - if (--userdata->counter == 0) { - userdata->destructor(userdata->ptr); - delete userdata; + Parameter::UserdataValue* userdata = parameter.value.userdataVal; + if (--userdata->counter == 0) + { + userdata->destructor(userdata->ptr); + delete userdata; + } + break; } - break; - } case ParameterType_Boolean: case ParameterType_Float: diff --git a/tests/Engine/Core/ParameterList.cpp b/tests/Engine/Core/ParameterList.cpp new file mode 100644 index 000000000..ef2729833 --- /dev/null +++ b/tests/Engine/Core/ParameterList.cpp @@ -0,0 +1,52 @@ +#include +#include + +#include + +SCENARIO("ParameterList", "[CORE][PARAMETERLIST]") +{ + GIVEN("An empty ParameterList") + { + Nz::ParameterList parameterList; + + WHEN("We add String 'string'") + { + Nz::String string("string"); + parameterList.SetParameter("string", string); + + THEN("We can get it back") + { + Nz::String newString; + REQUIRE(parameterList.GetStringParameter("string", &newString)); + REQUIRE(newString == string); + } + } + + WHEN("We add Float '3.f'") + { + float fl = 3.f; + parameterList.SetParameter("float", fl); + + THEN("We can get it back") + { + float newFl; + REQUIRE(parameterList.GetFloatParameter("float", &newFl)); + REQUIRE(newFl == fl); + } + } + + WHEN("We add Pointer to stack value") + { + int stackValue = 3; + void* ptrToStackValue = &stackValue; // Ugly conversion + parameterList.SetParameter("ptr", ptrToStackValue); + + THEN("We can get it back") + { + void* newPtrToStackValue = nullptr; + REQUIRE(parameterList.GetPointerParameter("ptr", &newPtrToStackValue)); + REQUIRE(newPtrToStackValue == ptrToStackValue); + } + } + } +} From 1eebeceeea640e46c1def0df6659ca1d8137c07d Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:24:37 +0100 Subject: [PATCH 107/229] Documentation for Primitive Former-commit-id: 8f4e15d4e9131836545f8b112049a001638f411c --- include/Nazara/Core/Primitive.inl | 272 ++++++++++++++++++++++++++++ src/Nazara/Core/PrimitiveList.cpp | 160 ++++++++++++++++ tests/Engine/Core/PrimitiveList.cpp | 31 ++++ 3 files changed, 463 insertions(+) create mode 100644 tests/Engine/Core/PrimitiveList.cpp diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index ce458739d..8aeecc5b6 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -6,6 +6,20 @@ namespace Nz { + /*! + * \class Nz::PrimitiveList + * \brief Core class that represents a geometric primitive + */ + + /*! + * \brief Makes a box centered + * + * \param lengths (Width, Height, Depht) + * \param subdivision Number of subdivision for the axis + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -15,11 +29,31 @@ namespace Nz box.subdivision = subdivision; } + /*! + * \brief Makes a box centered + * + * \param lengths (Width, Height, Depht) + * \param subdivision Number of subdivision for the axis + * \param position Position of the box + * \param rotation Rotation of the box + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeBox(lengths, subdivision, Matrix4f::Transform(position, rotation), uvCoords); } + /*! + * \brief Makes a cone, centered in (0, 0, 0) and circle in (0, -length, 0) + * + * \param length Height of the cone + * \param radius Width of the radius + * \param subdivision Number of sides for the circle + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -30,11 +64,31 @@ namespace Nz cone.subdivision = subdivision; } + /*! + * \brief Makes a cone, centered in (0, 0, 0) and circle in (0, -length, 0) + * + * \param length Height of the cone + * \param radius Width of the radius + * \param subdivision Number of sides for the circle + * \param position Position of the cone + * \param rotation Rotation of the cone + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeCone(length, radius, subdivision, Matrix4f::Transform(position, rotation), uvCoords); } + /*! + * \brief Makes a cubic sphere, centered in (0, 0, 0) + * + * \param size Radius of the cubic sphere + * \param subdivision Number of subdivision for the box + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -45,11 +99,30 @@ namespace Nz sphere.cubic.subdivision = subdivision; } + /*! + * \brief Adds a cubic sphere, centered in (0, 0, 0) + * + * \param size Radius of the cubic sphere + * \param subdivision Number of subdivision for the box + * \param position Position of the cubic sphere + * \param rotation Rotation of the cubic sphere + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeCubicSphere(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords); } + /*! + * \brief Makes a icosphere, centered in (0, 0, 0) + * + * \param size Radius of the icosphere + * \param recursionLevel Number of recursion for the icosphere + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -60,11 +133,30 @@ namespace Nz sphere.ico.recursionLevel = recursionLevel; } + /*! + * \brief Makes a icosphere, centered in (0, 0, 0) + * + * \param size Radius of the sphere + * \param recursionLevel Number of recursion for the icosphere + * \param position Position of the icosphere + * \param rotation Rotation of the icosphere + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeIcoSphere(size, recursionLevel, Matrix4f::Transform(position, rotation), uvCoords); } + /*! + * \brief Makes a plane, centered in (0, 0, 0) + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -74,16 +166,45 @@ namespace Nz plane.subdivision = subdivision; } + /*! + * \brief Makes a plane, centered in (0, 0, 0) + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param planeInfo Information for the plane + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo, const Rectf& uvCoords) { MakePlane(size, subdivision, Matrix4f::Transform(planeInfo.distance * planeInfo.normal, Quaternionf::RotationBetween(Vector3f::Up(), planeInfo.normal)), uvCoords); } + /*! + * \brief Makes a plane, centered in (0, 0, 0) + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param position Position of the plane + * \param rotation Rotation of the plane + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakePlane(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords); } + /*! + * \brief Makes a UV sphere, centered in (0, 0, 0) + * + * \param size Radius of the sphere + * \param sliceCount Number of slices + * \param stackCount Number of stacks + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -95,11 +216,32 @@ namespace Nz sphere.uv.stackCount = stackCount; } + /*! + * \brief Makes a UV sphere, centered in (0, 0, 0) + * + * \param size Radius of the sphere + * \param sliceCount Number of slices + * \param stackCount Number of stacks + * \param position Position of the box + * \param rotation Rotation of the box + * \param uvCoords Coordinates for texture + */ + inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeUVSphere(size, sliceCount, stackCount, Matrix4f::Transform(position, rotation), uvCoords); } + /*! + * \brief Creates a box centered + * \return Primitive which is a box + * + * \param lengths (Width, Height, Depht) + * \param subdivision Number of subdivision for the axis + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -108,6 +250,17 @@ namespace Nz return primitive; } + /*! + * \brief Creates a box centered + * \return Primitive which is a box + * + * \param lengths (Width, Height, Depht) + * \param subdivision Number of subdivision for the axis + * \param position Position of the box + * \param rotation Rotation of the box + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -116,6 +269,17 @@ namespace Nz return primitive; } + /*! + * \brief Creates a cone, centered in (0, 0, 0) and circle in (0, -length, 0) + * \return Primitive which is a cone + * + * \param length Height of the cone + * \param radius Width of the radius + * \param subdivision Number of sides for the circle + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -124,6 +288,18 @@ namespace Nz return primitive; } + /*! + * \brief Creates a cone, centered in (0, 0, 0) and circle in (0, -length, 0) + * \return Primitive which is a cone + * + * \param length Height of the cone + * \param radius Width of the radius + * \param subdivision Number of sides for the circle + * \param position Position of the cone + * \param rotation Rotation of the cone + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -132,6 +308,16 @@ namespace Nz return primitive; } + /*! + * \brief Creates a cubic sphere, centered in (0, 0, 0) + * \return Primitive which is a cubic sphere + * + * \param size Radius of the cubic sphere + * \param subdivision Number of subdivision for the box + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -140,6 +326,17 @@ namespace Nz return primitive; } + /*! + * \brief Creates a cubic sphere, centered in (0, 0, 0) + * \return Primitive which is a cubic sphere + * + * \param size Radius of the cubic sphere + * \param subdivision Number of subdivision for the box + * \param position Position of the cubic sphere + * \param rotation Rotation of the cubic sphere + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -148,6 +345,16 @@ namespace Nz return primitive; } + /*! + * \brief Creates a icosphere, centered in (0, 0, 0) + * \return Primitive which is a icosphere + * + * \param size Radius of the icosphere + * \param recursionLevel Number of recursion for the icosphere + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -156,6 +363,17 @@ namespace Nz return primitive; } + /*! + * \brief Creates a icosphere, centered in (0, 0, 0) + * \return Primitive which is a icosphere + * + * \param size Radius of the sphere + * \param recursionLevel Number of recursion for the icosphere + * \param position Position of the icosphere + * \param rotation Rotation of the icosphere + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -164,6 +382,16 @@ namespace Nz return primitive; } + /*! + * \brief Creates a plane, centered in (0, 0, 0) + * \return Primitive which is a plane + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -172,6 +400,16 @@ namespace Nz return primitive; } + /*! + * \brief Creates a plane, centered in (0, 0, 0) + * \return Primitive which is a plane + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param planeInfo Information for the plane + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords) { Primitive primitive; @@ -180,6 +418,17 @@ namespace Nz return primitive; } + /*! + * \brief Creates a plane, centered in (0, 0, 0) + * \return Primitive which is a plane + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param position Position of the plane + * \param rotation Rotation of the plane + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -188,6 +437,17 @@ namespace Nz return primitive; } + /*! + * \brief Creates a UV sphere, centered in (0, 0, 0) + * \return Primitive which is a uv sphere + * + * \param size Radius of the sphere + * \param sliceCount Number of slices + * \param stackCount Number of stacks + * \param transformMatrix Matrix to apply + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -196,6 +456,18 @@ namespace Nz return primitive; } + /*! + * \brief Creates a UV sphere, centered in (0, 0, 0) + * \return Primitive which is a uv sphere + * + * \param size Radius of the sphere + * \param sliceCount Number of slices + * \param stackCount Number of stacks + * \param position Position of the box + * \param rotation Rotation of the box + * \param uvCoords Coordinates for texture + */ + inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index a9d2fc6ee..644f46e66 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -8,71 +8,199 @@ namespace Nz { + /*! + * \class Nz::PrimitiveList + * \brief Core class that represents a list of geometric primitives + */ + + /*! + * \brief Adds a box centered + * + * \param lengths (Width, Height, Depht) + * \param subdivision Number of subdivision for the axis + * \param transformMatrix Matrix to apply + */ + void PrimitiveList::AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix) { m_primitives.push_back(Primitive::Box(lengths, subdivision, transformMatrix)); } + /*! + * \brief Adds a box centered + * + * \param lengths (Width, Height, Depht) + * \param subdivision Number of subdivision for the axis + * \param position Position of the box + * \param rotation Rotation of the box + */ + void PrimitiveList::AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation) { m_primitives.push_back(Primitive::Box(lengths, subdivision, position, rotation)); } + /*! + * \brief Adds a cone, centered in (0, 0, 0) and circle in (0, -length, 0) + * + * \param length Height of the cone + * \param radius Width of the radius + * \param subdivision Number of sides for the circle + * \param transformMatrix Matrix to apply + */ + void PrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix) { m_primitives.push_back(Primitive::Cone(length, radius, subdivision, transformMatrix)); } + /*! + * \brief Adds a cone, centered in (0, 0, 0) and circle in (0, -length, 0) + * + * \param length Height of the cone + * \param radius Width of the radius + * \param subdivision Number of sides for the circle + * \param position Position of the cone + * \param rotation Rotation of the cone + */ + void PrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation) { m_primitives.push_back(Primitive::Cone(length, radius, subdivision, position, rotation)); } + /*! + * \brief Adds a cubic sphere, centered in (0, 0, 0) + * + * \param size Radius of the cubic sphere + * \param subdivision Number of subdivision for the box + * \param transformMatrix Matrix to apply + */ + void PrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix) { m_primitives.push_back(Primitive::CubicSphere(size, subdivision, transformMatrix)); } + /*! + * \brief Adds a cubic sphere, centered in (0, 0, 0) + * + * \param size Radius of the cubic sphere + * \param subdivision Number of subdivision for the box + * \param position Position of the cubic sphere + * \param rotation Rotation of the cubic sphere + */ + void PrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation) { m_primitives.push_back(Primitive::CubicSphere(size, subdivision, position, rotation)); } + /*! + * \brief Adds a icosphere, centered in (0, 0, 0) + * + * \param size Radius of the icosphere + * \param recursionLevel Number of recursion for the icosphere + * \param transformMatrix Matrix to apply + */ + void PrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix) { m_primitives.push_back(Primitive::IcoSphere(size, recursionLevel, transformMatrix)); } + /*! + * \brief Adds a icosphere, centered in (0, 0, 0) + * + * \param size Radius of the sphere + * \param recursionLevel Number of recursion for the icosphere + * \param position Position of the icosphere + * \param rotation Rotation of the icosphere + */ + void PrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation) { m_primitives.push_back(Primitive::IcoSphere(size, recursionLevel, position, rotation)); } + /*! + * \brief Adds a plane, centered in (0, 0, 0) + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param transformMatrix Matrix to apply + */ + void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix) { m_primitives.push_back(Primitive::Plane(size, subdivision, transformMatrix)); } + /*! + * \brief Adds a plane, centered in (0, 0, 0) + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param planeInfo Information for the plane + */ + void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo) { m_primitives.push_back(Primitive::Plane(size, subdivision, planeInfo)); } + /*! + * \brief Adds a plane, centered in (0, 0, 0) + * + * \param size (Width, Depth) + * \param subdivision Number of subdivision for the axis + * \param position Position of the plane + * \param rotation Rotation of the plane + */ + void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation) { m_primitives.push_back(Primitive::Plane(size, subdivision, position, rotation)); } + /*! + * \brief Adds a UV sphere, centered in (0, 0, 0) + * + * \param size Radius of the sphere + * \param sliceCount Number of slices + * \param stackCount Number of stacks + * \param transformMatrix Matrix to apply + */ + void PrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix) { m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, transformMatrix)); } + /*! + * \brief Adds a UV sphere, centered in (0, 0, 0) + * + * \param size Radius of the sphere + * \param sliceCount Number of slices + * \param stackCount Number of stacks + * \param position Position of the box + * \param rotation Rotation of the box + */ + void PrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation) { m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, position, rotation)); } + /*! + * \brief Gets the ith primitive + * \return A reference to the ith primitive + * + * \param i Index of the primitive + * + * \remark Produces a NazaraAssert if index is greather than the size + */ + Primitive& PrimitiveList::GetPrimitive(std::size_t i) { NazaraAssert(i < m_primitives.size(), "Primitive index out of range"); @@ -80,6 +208,15 @@ namespace Nz return m_primitives[i]; } + /*! + * \brief Gets the ith primitive + * \return A constant reference to the ith primitive + * + * \param i Index of the primitive + * + * \remark Produces a NazaraAssert if index is greather than the size + */ + const Primitive& PrimitiveList::GetPrimitive(std::size_t i) const { NazaraAssert(i < m_primitives.size(), "Primitive index out of range"); @@ -87,16 +224,39 @@ namespace Nz return m_primitives[i]; } + /*! + * \brief Gets the number of primitives + * \return Number of primitives + */ + std::size_t PrimitiveList::GetSize() const { return m_primitives.size(); } + /*! + * \brief Gets the ith primitive + * \return A reference to the ith primitive + * + * \param i Index of the primitive + * + * \remark Produces a NazaraAssert if index is greather than the size + */ + Primitive& PrimitiveList::operator()(unsigned int i) { return GetPrimitive(i); } + /*! + * \brief Gets the ith primitive + * \return A constant reference to the ith primitive + * + * \param i Index of the primitive + * + * \remark Produces a NazaraAssert if index is greather than the size + */ + const Primitive& PrimitiveList::operator()(unsigned int i) const { return GetPrimitive(i); diff --git a/tests/Engine/Core/PrimitiveList.cpp b/tests/Engine/Core/PrimitiveList.cpp new file mode 100644 index 000000000..84a39cac2 --- /dev/null +++ b/tests/Engine/Core/PrimitiveList.cpp @@ -0,0 +1,31 @@ +#include +#include + +SCENARIO("PrimitiveList", "[CORE][PRIMITIVELIST]") +{ + GIVEN("An empty PrimitiveList") + { + Nz::PrimitiveList primitiveList; + + WHEN("We add two primitives") + { + float size = 1.f; + unsigned int subdivision = 1; + unsigned int recursionLevel = 1; + Nz::Matrix4f identity = Nz::Matrix4f::Identity(); + + primitiveList.AddCubicSphere(size, subdivision, identity); + primitiveList.AddIcoSphere(size, subdivision, identity); + + THEN("There must be two items") + { + REQUIRE(primitiveList.GetSize() == 2); + } + + THEN("The first one is the cubic sphere") + { + REQUIRE(primitiveList(0).sphere.type == Nz::SphereType_Cubic); + } + } + } +} From 1d5518b0d3e4455f51959cf7d4d62c7f70e7286c Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:25:26 +0100 Subject: [PATCH 108/229] Documentation for RefCounted Former-commit-id: 45bd646d027ba91fc3d399631fc0518ba172385d --- src/Nazara/Core/RefCounted.cpp | 46 ++++++++++++++++++++++++++++++++ tests/Engine/Core/RefCounted.cpp | 29 ++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 tests/Engine/Core/RefCounted.cpp diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index db6ea7edf..f2ef2b926 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -16,12 +16,29 @@ namespace Nz { + /*! + * \class Nz::RefCounted + * \brief Core class that represents a reference with a counter + */ + + /*! + * \brief Constructs a RefCounted object with a persistance aspect + * + * \param persistent if false, object is destroyed when no more referenced + */ + RefCounted::RefCounted(bool persistent) : m_persistent(persistent), m_referenceCount(0) { } + /*! + * \brief Destructs the object + * + * \remark Produces a NazaraWarning if still referenced with NAZARA_CORE_SAFE defined + */ + RefCounted::~RefCounted() { #if NAZARA_CORE_SAFE @@ -30,21 +47,42 @@ namespace Nz #endif } + /*! + * \brief Adds a reference to the object + */ + void RefCounted::AddReference() const { m_referenceCount++; } + /*! + * \brief Gets the number of references to the object + * \return Number of references + */ + unsigned int RefCounted::GetReferenceCount() const { return m_referenceCount; } + /*! + * \brief Checks whether the object is persistent + * \return true if object is not destroyed when no more referenced + */ + bool RefCounted::IsPersistent() const { return m_persistent; } + /*! + * \brief Removes a reference to the object + * \return true if object is deleted because no more referenced + * + * \remark Produces a NazaraError if counter is already 0 with NAZARA_CORE_SAFE defined + */ + bool RefCounted::RemoveReference() const { #if NAZARA_CORE_SAFE @@ -65,6 +103,14 @@ namespace Nz return false; } + /*! + * \brief Sets the persistence of the object + * \return true if object is deleted because no more referenced + * + * \param persistent Sets the persistence of the object + * \param checkReferenceCount Checks if the object should be destroyed if true + */ + bool RefCounted::SetPersistent(bool persistent, bool checkReferenceCount) { m_persistent = persistent; diff --git a/tests/Engine/Core/RefCounted.cpp b/tests/Engine/Core/RefCounted.cpp new file mode 100644 index 000000000..0201f0beb --- /dev/null +++ b/tests/Engine/Core/RefCounted.cpp @@ -0,0 +1,29 @@ +#include +#include + +SCENARIO("RefCounted", "[CORE][REFCOUNTED]") +{ + GIVEN("A refcounted persistent") + { + Nz::RefCounted refCounted; + REQUIRE(refCounted.IsPersistent() == true); + + WHEN("We add a reference to this persistent object") + { + THEN("Number of references should be one") + { + refCounted.AddReference(); + REQUIRE(refCounted.GetReferenceCount() == 1); + REQUIRE(refCounted.RemoveReference() == false); + } + + AND_THEN("We suppress the reference, object is still alive") + { + refCounted.AddReference(); + REQUIRE(refCounted.IsPersistent()); + REQUIRE(refCounted.RemoveReference() == false); + REQUIRE(refCounted.GetReferenceCount() == 0); + } + } + } +} From fe12806c6bff17e3c50fb367a8a59e76c0cbb578 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:26:10 +0100 Subject: [PATCH 109/229] Documentation for Signal Former-commit-id: 8c69830fe9e23ec85ced5f29ce43c96ea26298eb --- include/Nazara/Core/Signal.inl | 179 ++++++++++++++++++++++++++++++++- tests/Engine/Core/Signal.cpp | 48 +++++++++ 2 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 tests/Engine/Core/Signal.cpp diff --git a/include/Nazara/Core/Signal.inl b/include/Nazara/Core/Signal.inl index a635302ec..de1609d78 100644 --- a/include/Nazara/Core/Signal.inl +++ b/include/Nazara/Core/Signal.inl @@ -8,18 +8,37 @@ namespace Nz { + /*! + * \class Nz::Signal + * \brief Core class that represents a signal, a list of objects waiting for its message + */ + + /*! + * \brief Constructs a Signal object by default + */ + template Signal::Signal() : m_slotIterator(0) { } + /*! + * \brief Constructs a Signal object by move semantic + * + * \param signal Signal to move in this + */ + template Signal::Signal(Signal&& signal) { operator=(std::move(signal)); } + /*! + * \brief Clears the list of actions attached to the signal + */ + template void Signal::Clear() { @@ -27,12 +46,26 @@ namespace Nz m_slotIterator = 0; } + /*! + * \brief Connects a function to the signal + * \return Connection attached to the signal + * + * \param func Non-member function + */ + template typename Signal::Connection Signal::Connect(const Callback& func) { return Connect(Callback(func)); } + /*! + * \brief Connects a function to the signal + * \return Connection attached to the signal + * + * \param func Non-member function + */ + template typename Signal::Connection Signal::Connect(Callback&& func) { @@ -54,6 +87,14 @@ namespace Nz return Connection(m_slots.back()); } + /*! + * \brief Connects a member function and its object to the signal + * \return Connection attached to the signal + * + * \param object Object to send the message + * \param method Member function + */ + template template typename Signal::Connection Signal::Connect(O& object, void (O::*method) (Args...)) @@ -64,6 +105,14 @@ namespace Nz }); } + /*! + * \brief Connects a member function and its object to the signal + * \return Connection attached to the signal + * + * \param object Object to send the message + * \param method Member function + */ + template template typename Signal::Connection Signal::Connect(O* object, void (O::*method)(Args...)) @@ -74,6 +123,14 @@ namespace Nz }); } + /*! + * \brief Connects a member function and its object to the signal + * \return Connection attached to the signal + * + * \param object Object to send the message + * \param method Member function + */ + template template typename Signal::Connection Signal::Connect(const O& object, void (O::*method) (Args...) const) @@ -84,6 +141,14 @@ namespace Nz }); } + /*! + * \brief Connects a member function and its object to the signal + * \return Connection attached to the signal + * + * \param object Object to send the message + * \param method Member function + */ + template template typename Signal::Connection Signal::Connect(const O* object, void (O::*method)(Args...) const) @@ -94,6 +159,12 @@ namespace Nz }); } + /*! + * \brief Applies the list of arguments to every callback functions + * + * \param args Arguments to send with the message + */ + template void Signal::operator()(Args... args) const { @@ -101,6 +172,13 @@ namespace Nz m_slots[m_slotIterator]->callback(args...); } + /*! + * \brief Moves the signal into this + * \return A reference to this + * + * \param signal Signal to move in this + */ + template Signal& Signal::operator=(Signal&& signal) { @@ -114,17 +192,28 @@ namespace Nz return *this; } + /*! + * \brief Disconnects a listener from this signal + * + * \param slot Pointer to the ith listener of the signal + * + * \remark Produces a NazaraAssert if slot is invalid (nullptr) + * \remark Produces a NazaraAssert if index of slot is invalid + * \remark Produces a NazaraAssert if slot is not attached to this signal + */ + template void Signal::Disconnect(const SlotPtr& slot) { NazaraAssert(slot, "Invalid slot pointer"); NazaraAssert(slot->index < m_slots.size(), "Invalid slot index"); + NazaraAssert(slot->signal == this, "Slot is not attached to this signal"); // "Swap this slot with the last one and pop" idiom // This will preserve slot indexes // Can we safely "remove" this slot? - if (m_slotIterator >= m_slots.size()-1 || slot->index > m_slotIterator) + if (m_slotIterator >= (m_slots.size() - 1) || slot->index > m_slotIterator) { // Yes we can SlotPtr& newSlot = m_slots[slot->index]; @@ -150,6 +239,16 @@ namespace Nz m_slots.pop_back(); } + /*! + * \class Nz::Signal::Connection + * \brief Core class that represents a connection attached to a signal + */ + + /*! + * \brief Constructs a Signal::Connection object with a slot + * + * \param slot Slot of the listener + */ template Signal::Connection::Connection(const SlotPtr& slot) : @@ -157,6 +256,13 @@ namespace Nz { } + /*! + * \brief Connects to a signal with arguments + * + * \param signal New signal to listen + * \param args Arguments for the signal + */ + template template void Signal::Connection::Connect(BaseClass& signal, ConnectArgs&&... args) @@ -164,6 +270,10 @@ namespace Nz operator=(signal.Connect(std::forward(args)...)); } + /*! + * \brief Disconnects the connection from the signal + */ + template void Signal::Connection::Disconnect() { @@ -171,12 +281,27 @@ namespace Nz ptr->signal->Disconnect(ptr); } + /*! + * \brief Checks whether the connection is still active with the signal + * \return true if signal is still active + */ + template bool Signal::Connection::IsConnected() const { return !m_ptr.expired(); } + /*! + * \class Nz::Signal::ConnectionGuard + * \brief Core class that represents a RAII for a connection attached to a signal + */ + + /*! + * \brief Constructs a Signal::ConnectionGuard object with a connection + * + * \param connection Connection for the scope + */ template Signal::ConnectionGuard::ConnectionGuard(const Connection& connection) : @@ -184,18 +309,35 @@ namespace Nz { } + /*! + * \brief Constructs a Signal::ConnectionGuard object with a connection by move semantic + * + * \param connection Connection for the scope + */ + template Signal::ConnectionGuard::ConnectionGuard(Connection&& connection) : m_connection(std::move(connection)) { } + /*! + * \brief Destructs the object and disconnects the connection + */ + template Signal::ConnectionGuard::~ConnectionGuard() { m_connection.Disconnect(); } + /*! + * \brief Connects to a signal with arguments + * + * \param signal New signal to listen + * \param args Arguments for the signal + */ + template template void Signal::ConnectionGuard::Connect(BaseClass& signal, ConnectArgs&&... args) @@ -204,24 +346,45 @@ namespace Nz m_connection.Connect(signal, std::forward(args)...); } + /*! + * \brief Disconnects the connection from the signal + */ + template void Signal::ConnectionGuard::Disconnect() { m_connection.Disconnect(); } + /*! + * \brief Gets the connection attached to the signal + * \return Connection of the signal + */ + template typename Signal::Connection& Signal::ConnectionGuard::GetConnection() { return m_connection; } + /*! + * \brief Checks whether the connection is still active with the signal + * \return true if signal is still active + */ + template bool Signal::ConnectionGuard::IsConnected() const { return m_connection.IsConnected(); } + /*! + * \brief Assigns the connection into this + * \return A reference to this + * + * \param connection Connection to assign into this + */ + template typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(const Connection& connection) { @@ -231,6 +394,13 @@ namespace Nz return *this; } + /*! + * \brief Moves the Connection into this + * \return A reference to this + * + * \param connection Connection to move in this + */ + template typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(Connection&& connection) { @@ -240,6 +410,13 @@ namespace Nz return *this; } + /*! + * \brief Moves the ConnectionGuard into this + * \return A reference to this + * + * \param connection ConnectionGuard to move in this + */ + template typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(ConnectionGuard&& connection) { diff --git a/tests/Engine/Core/Signal.cpp b/tests/Engine/Core/Signal.cpp new file mode 100644 index 000000000..c5582d866 --- /dev/null +++ b/tests/Engine/Core/Signal.cpp @@ -0,0 +1,48 @@ +#include +#include + +struct Incrementer +{ + void increment(int* inc) + { + *inc += 1; + } +}; + +void increment(int* inc) +{ + *inc += 1; +} + +SCENARIO("Signal", "[CORE][SIGNAL]") +{ + GIVEN("A signal") + { + Nz::Signal signal; + + WHEN("We connection different callbacks") + { + auto connection = signal.Connect(increment); + signal.Connect([](int* inc){ *inc += 1; }); + Incrementer incrementer; + signal.Connect(incrementer, &Incrementer::increment); + + THEN("The call of signal with inc = 0 must return 3") + { + int inc = 0; + signal(&inc); + REQUIRE(inc == 3); + } + + AND_THEN("When we disconnect one function, there should be only two listeners") + { + connection.Disconnect(); + REQUIRE(!connection.IsConnected()); + + int inc = 0; + signal(&inc); + REQUIRE(inc == 2); + } + } + } +} From e311dcb5d3356aadb5da5c66034ea0bce01ddd95 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:26:49 +0100 Subject: [PATCH 110/229] Documentation for SparsePtr Former-commit-id: f4e51b1a9d7792dbbbd148e028906ba8062787b5 --- include/Nazara/Core/SparsePtr.hpp | 2 +- include/Nazara/Core/SparsePtr.inl | 247 ++++++++++++++++++++++++++++-- tests/Engine/Core/SparsePtr.cpp | 47 ++++++ 3 files changed, 281 insertions(+), 15 deletions(-) create mode 100644 tests/Engine/Core/SparsePtr.cpp diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 79c87ca95..6e36fcc57 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -7,7 +7,7 @@ #ifndef NAZARA_SPARSEPTR_HPP #define NAZARA_SPARSEPTR_HPP -///FIXME: Est-ce que SparsePtr est vraiment le meilleur nom pour cette classe ? +///FIXME: Is SparsePtr a really good name for this class ? #include #include diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index d6b227226..31e83addd 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -7,24 +7,52 @@ namespace Nz { + /*! + * \class Nz::SparsePtr + * \brief Core class that represents a pointer and the step between two elements + */ + + /*! + * \brief Constructs a SparsePtr object by default + */ + template SparsePtr::SparsePtr() { Reset(); } + /*! + * \brief Constructs a SparsePtr object with a pointer + * + * \param ptr Pointer to data + */ + template SparsePtr::SparsePtr(T* ptr) { Reset(ptr); } + /*! + * \brief Constructs a SparsePtr object with a pointer and a step + * + * \param ptr Pointer to data + * \param stride Step between two elements + */ + template SparsePtr::SparsePtr(VoidPtr ptr, int stride) { Reset(ptr, stride); } + /*! + * \brief Constructs a SparsePtr object from another type of SparsePtr + * + * \param ptr Pointer to data of type U to convert to type T + */ + template template SparsePtr::SparsePtr(const SparsePtr& ptr) @@ -32,18 +60,32 @@ namespace Nz Reset(ptr); } + /*! + * \brief Gets the original pointer + * \return Pointer to the first data + */ + template typename SparsePtr::VoidPtr SparsePtr::GetPtr() const { return m_ptr; } + /*! + * \brief Gets the stride + * \return Step between two elements + */ + template int SparsePtr::GetStride() const { return m_stride; } + /*! + * \brief Resets the SparsePtr + */ + template void SparsePtr::Reset() { @@ -51,6 +93,14 @@ namespace Nz SetStride(0); } + /*! + * \brief Resets the SparsePtr with a pointer + * + * \param ptr Pointer to data + * + * \remark stride is set to sizeof(T) + */ + template void SparsePtr::Reset(T* ptr) { @@ -58,6 +108,13 @@ namespace Nz SetStride(sizeof(T)); } + /*! + * \brief Resets the SparsePtr with a pointer and its stride + * + * \param ptr Pointer to data + * \param stride Step between two elements + */ + template void SparsePtr::Reset(VoidPtr ptr, int stride) { @@ -65,6 +122,12 @@ namespace Nz SetStride(stride); } + /*! + * \brief Resets the SparsePtr with another SparsePtr + * + * \param ptr Another sparsePtr + */ + template void SparsePtr::Reset(const SparsePtr& ptr) { @@ -72,6 +135,12 @@ namespace Nz SetStride(ptr.GetStride()); } + /*! + * \brief Resets the SparsePtr with another type of SparsePtr + * + * \param ptr Another sparsePtr + */ + template template void SparsePtr::Reset(const SparsePtr& ptr) @@ -82,94 +151,187 @@ namespace Nz SetStride(ptr.GetStride()); } + /*! + * \brief Sets the pointer + * + * \param ptr Pointer to data + */ + template void SparsePtr::SetPtr(VoidPtr ptr) { m_ptr = reinterpret_cast(ptr); } + /*! + * \brief Sets the stride + * + * \param stride Step between two elements + */ + template void SparsePtr::SetStride(int stride) { m_stride = stride; } + /*! + * \brief Converts the pointer to bool + * \return true if pointer is not nullptr + */ + template SparsePtr::operator bool() const { return m_ptr != nullptr; } + /*! + * \brief Converts the pointer to a pointer to the value + * \return The value of the pointer + */ + template SparsePtr::operator T*() const { return reinterpret_cast(m_ptr); } + /*! + * \brief Dereferences the pointer + * \return The dereferencing of the pointer + */ + template T& SparsePtr::operator*() const { return *reinterpret_cast(m_ptr); } + /*! + * \brief Dereferences the pointer + * \return The dereferencing of the pointer + */ + template T* SparsePtr::operator->() const { return reinterpret_cast(m_ptr); } + /*! + * \brief Gets the ith element of the stride pointer + * \return A reference to the ith value + * + * \param index Number of stride to do + */ + template T& SparsePtr::operator[](int index) const { - return *reinterpret_cast(m_ptr + index*m_stride); + return *reinterpret_cast(m_ptr + index * m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator+(int count) const { - return SparsePtr(m_ptr + count*m_stride, m_stride); + return SparsePtr(m_ptr + count * m_stride, m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator+(unsigned int count) const { - return SparsePtr(m_ptr + count*m_stride, m_stride); + return SparsePtr(m_ptr + count * m_stride, m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator-(int count) const { - return SparsePtr(m_ptr - count*m_stride, m_stride); + return SparsePtr(m_ptr - count * m_stride, m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator-(unsigned int count) const { - return SparsePtr(m_ptr - count*m_stride, m_stride); + return SparsePtr(m_ptr - count * m_stride, m_stride); } + /*! + * \brief Gets the difference between the two SparsePtr + * \return The difference of elements: ptr - this->ptr + * + * \param ptr Other ptr + */ + template std::ptrdiff_t SparsePtr::operator-(const SparsePtr& ptr) const { - return (m_ptr - ptr.m_ptr)/m_stride; + return (m_ptr - ptr.m_ptr) / m_stride; } + /*! + * \brief Gets the SparsePtr with an offset + * \return A reference to this pointer with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr& SparsePtr::operator+=(int count) { - m_ptr += count*m_stride; + m_ptr += count * m_stride; return *this; } + /*! + * \brief Gets the SparsePtr with an offset + * \return A reference to this pointer with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr& SparsePtr::operator-=(int count) { - m_ptr -= count*m_stride; + m_ptr -= count * m_stride; return *this; } + /*! + * \brief Gets the SparsePtr with the next element + * \return A reference to this pointer updated + */ + template SparsePtr& SparsePtr::operator++() { @@ -178,19 +340,29 @@ namespace Nz return *this; } + /*! + * \brief Gets the SparsePtr with the next element + * \return A SparsePtr not updated + */ + template SparsePtr SparsePtr::operator++(int) { - // On fait une copie de l'objet + // We copy the object SparsePtr tmp(*this); - // On modifie l'objet + // We modify it operator++(); - // On retourne la copie + // We return the copy return tmp; } + /*! + * \brief Gets the SparsePtr with the previous element + * \return A reference to this pointer updated + */ + template SparsePtr& SparsePtr::operator--() { @@ -198,49 +370,96 @@ namespace Nz return *this; } + /*! + * \brief Gets the SparsePtr with the previous element + * \return A SparsePtr not updated + */ + template SparsePtr SparsePtr::operator--(int) { - // On fait une copie de l'objet + // We copy the object SparsePtr tmp(*this); - // On modifie l'objet + // We modify it operator--(); - // On retourne la copie + // We return the copy return tmp; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the two SparsePtr are pointing to the same memory + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator==(const SparsePtr& ptr) const { return m_ptr == ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return false if the two SparsePtr are pointing to the same memory + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator!=(const SparsePtr& ptr) const { return m_ptr != ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory inferior to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator<(const SparsePtr& ptr) const { return m_ptr < ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory superior to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator>(const SparsePtr& ptr) const { return m_ptr > ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory inferior or equal to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator<=(const SparsePtr& ptr) const { return m_ptr <= ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory superior or equal to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator>=(const SparsePtr& ptr) const { diff --git a/tests/Engine/Core/SparsePtr.cpp b/tests/Engine/Core/SparsePtr.cpp new file mode 100644 index 000000000..6979549a3 --- /dev/null +++ b/tests/Engine/Core/SparsePtr.cpp @@ -0,0 +1,47 @@ +#include +#include + +#include + +SCENARIO("SparsePtr", "[CORE][SPARSEPTR]") +{ + GIVEN("A sparse pointer pointing to an array with a stride of 2") + { + std::array arrays{0, 1, 2, 3, 4}; + Nz::SparsePtr sparsePtr(arrays.begin(), 2 * sizeof(int)); + + WHEN("We use operators") + { + THEN("Operator[] with 2 should be 4") + { + REQUIRE(4 == sparsePtr[2]); + } + + THEN("Operator++ and Operator-- should be opposite") + { + ++sparsePtr; + REQUIRE(2 == *sparsePtr); + auto old = sparsePtr++; + REQUIRE(2 == *old); + REQUIRE(4 == *sparsePtr); + + --sparsePtr; + REQUIRE(2 == *sparsePtr); + auto oldMinus = sparsePtr--; + REQUIRE(2 == *oldMinus); + REQUIRE(0 == *sparsePtr); + } + + THEN("Operator+ and operator-") + { + auto offsetTwo = sparsePtr + 2; + REQUIRE(4 == *offsetTwo); + + auto offsetZero = offsetTwo - 2; + REQUIRE(0 == *offsetZero); + + REQUIRE((offsetTwo - offsetZero) == 2); + } + } + } +} From f16857fc6a4ffd590f7196d6ab65a33378c78386 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:27:29 +0100 Subject: [PATCH 111/229] Documentation for Resource Former-commit-id: 7da8bc4261566c89030eb0226a29b1a70183e68a --- include/Nazara/Core/ResourceLoader.inl | 111 ++++++++++++++++++++++-- include/Nazara/Core/ResourceManager.inl | 57 +++++++++++- src/Nazara/Core/Resource.cpp | 16 ++++ 3 files changed, 175 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index e3f7c4577..e58ec1b33 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -11,6 +11,18 @@ namespace Nz { + /*! + * \class Nz::ResourceLoader + * \brief Core class that represents a loader of resources + */ + + /*! + * \brief Checks whether the extension of the file is supported + * \return true if supported + * + * \param extension Extension of the file + */ + template bool ResourceLoader::IsExtensionSupported(const String& extension) { @@ -25,10 +37,32 @@ namespace Nz return false; } + /*! + * \brief Loads a resource from a filepath and parameters + * \return true if successfully loaded + * + * \param resource Resource to load + * \param filePath Path to the resource + * \param parameters Parameters for the load + * + * \remark Produces a NazaraError if resource is nullptr with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraError if parameters are invalid with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraError if filePath has no extension + * \remark Produces a NazaraError if file count not be opened + * \remark Produces a NazaraWarning if loader failed + * \remark Produces a NazaraError if all loaders failed or no loader was found + */ + template bool ResourceLoader::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters) { #if NAZARA_CORE_SAFE + if (!resource) + { + NazaraError("Pointer invalid"); + return false; + } + if (!parameters.IsValid()) { NazaraError("Invalid parameters"); @@ -122,13 +156,29 @@ namespace Nz return false; } + /*! + * \brief Loads a resource from a raw memory, a size and parameters + * \return true if successfully loaded + * + * \param resource Resource to load + * \param data Raw memory of the resource + * \param size Size available for the read + * \param parameters Parameters for the load + * + * \remark Produces a NazaraError if resource is nullptr with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraError if size is 0 with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraError if parameters are invalid with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraWarning if loader failed + * \remark Produces a NazaraError if all loaders failed or no loader was found + */ + template bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) { #if NAZARA_CORE_SAFE - if (!parameters.IsValid()) + if (!resource) { - NazaraError("Invalid parameters"); + NazaraError("Pointer invalid"); return false; } @@ -137,6 +187,12 @@ namespace Nz NazaraError("No data to load"); return false; } + + if (!parameters.IsValid()) + { + NazaraError("Invalid parameters"); + return false; + } #endif MemoryView stream(data, size); @@ -198,13 +254,28 @@ namespace Nz return false; } + /*! + * \brief Loads a resource from a stream and parameters + * \return true if successfully loaded + * + * \param resource Resource to load + * \param stream Stream of the resource + * \param parameters Parameters for the load + * + * \remark Produces a NazaraError if resource is nullptr with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraError if stream has no data with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraError if parameters are invalid with NAZARA_CORE_SAFE defined + * \remark Produces a NazaraWarning if loader failed + * \remark Produces a NazaraError if all loaders failed or no loader was found + */ + template bool ResourceLoader::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters) { #if NAZARA_CORE_SAFE - if (!parameters.IsValid()) + if (!resource) { - NazaraError("Invalid parameters"); + NazaraError("Pointer invalid"); return false; } @@ -213,6 +284,12 @@ namespace Nz NazaraError("No data to load"); return false; } + + if (!parameters.IsValid()) + { + NazaraError("Invalid parameters"); + return false; + } #endif UInt64 streamPos = stream.GetCursorPos(); @@ -224,17 +301,17 @@ namespace Nz stream.SetCursorPos(streamPos); - // Le loader supporte-t-il les données ? + // Does the loader support these data ? Ternary recognized = checkFunc(stream, parameters); if (recognized == Ternary_False) continue; else if (recognized == Ternary_True) found = true; - // On repositionne le stream à son ancienne position + // We move the stream to its old position stream.SetCursorPos(streamPos); - // Chargement de la ressource + // Load of the resource if (streamLoader(resource, stream, parameters)) return true; @@ -250,6 +327,16 @@ namespace Nz return false; } + /*! + * \brief Registers the loader + * + * \param extensionGetter A function to test whether the extension (as a string) is supported by this loader + * \param checkFunc A function to check the stream with the parser + * \param streamLoader A function to load the data from a stream in the resource + * \param fileLoader Optional function to load the data from a file in the resource + * \param memoryLoader Optional function to load the data from a raw memory in the resource + */ + template void ResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { @@ -272,6 +359,16 @@ namespace Nz Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } + /*! + * \brief Unregisters the loader + * + * \param extensionGetter A function to test whether the extension (as a string) is supported by this loader + * \param checkFunc A function to check the stream with the parser + * \param streamLoader A function to load the data from a stream in the resource + * \param fileLoader Optional function to load the data from a file in the resource + * \param memoryLoader Optional function to load the data from a raw memory in the resource + */ + template void ResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { diff --git a/include/Nazara/Core/ResourceManager.inl b/include/Nazara/Core/ResourceManager.inl index c5f37237e..9c8dc903b 100644 --- a/include/Nazara/Core/ResourceManager.inl +++ b/include/Nazara/Core/ResourceManager.inl @@ -9,12 +9,28 @@ namespace Nz { + /*! + * \class Nz::ResourceManager + * \brief Core class that represents a resource manager + */ + + /*! + * \brief Clears the content of the manager + */ + template void ResourceManager::Clear() { Type::s_managerMap.clear(); } + /*! + * \brief Gets a reference to the object loaded from file + * \return Reference to the object + * + * \param filePath Path to the asset that will be loaded + */ + template ObjectRef ResourceManager::Get(const String& filePath) { @@ -43,12 +59,21 @@ namespace Nz return it->second; } + /*! + * \brief Gets the defaults parameters for the load + * \return Default parameters for loading from file + */ + template const Parameters& ResourceManager::GetDefaultParameters() { return Type::s_managerParameters; } + /*! + * \brief Purges the resource manager from every asset whose it is the only owner + */ + template void ResourceManager::Purge() { @@ -56,16 +81,23 @@ namespace Nz while (it != Type::s_managerMap.end()) { const ObjectRef& ref = it->second; - if (ref.GetReferenceCount() == 1) // Sommes-nous les seuls à détenir la ressource ? + if (ref.GetReferenceCount() == 1) // Are we the only ones to own the resource ? { NazaraDebug("Purging resource from file " + ref->GetFilePath()); - Type::s_managerMap.erase(it++); // Alors on la supprime + Type::s_managerMap.erase(it++); // Then we erase it } else ++it; } } + /*! + * \brief Registers the resource under the filePath + * + * \param filePath Path for the resource + * \param resource Object to associate with + */ + template void ResourceManager::Register(const String& filePath, ObjectRef resource) { @@ -74,12 +106,24 @@ namespace Nz Type::s_managerMap[absolutePath] = resource; } + /*! + * \brief Sets the defaults parameters for the load + * + * \param params Default parameters for loading from file + */ + template void ResourceManager::SetDefaultParameters(const Parameters& params) { Type::s_managerParameters = params; } + /*! + * \brief Unregisters the resource under the filePath + * + * \param filePath Path for the resource + */ + template void ResourceManager::Unregister(const String& filePath) { @@ -88,12 +132,21 @@ namespace Nz Type::s_managerMap.erase(absolutePath); } + /*! + * \brief Initializes the resource manager + * \return true + */ + template bool ResourceManager::Initialize() { return true; } + /*! + * \brief Uninitialize the resource manager + */ + template void ResourceManager::Uninitialize() { diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 080e4fd22..23fa6ea22 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -7,13 +7,29 @@ namespace Nz { + /*! + * \class Nz::Resource + * \brief Core class that represents a resource + */ + Resource::~Resource() = default; + /*! + * \brief Gets the file path associated with the resource + * \return A reference to the path + */ + const String& Resource::GetFilePath() const { return m_filePath; } + /*! + * \brief Sets the file path associated with the resource + * + * \param filePath Path to the resource + */ + void Resource::SetFilePath(const String& filePath) { m_filePath = filePath; From 44ec6caf5df53065d16ad5e283b800796c6b9e56 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:28:17 +0100 Subject: [PATCH 112/229] Documentation for Memory Former-commit-id: 85e41e916df2c2e2bffa31f5540643144223a322 --- include/Nazara/Core/MemoryHelper.inl | 29 ++++++++- include/Nazara/Core/MemoryStream.inl | 25 ++++++++ src/Nazara/Core/MemoryManager.cpp | 96 +++++++++++++++++++++++++++- src/Nazara/Core/MemoryStream.cpp | 68 +++++++++++++++++++- src/Nazara/Core/MemoryView.cpp | 69 ++++++++++++++++++++ 5 files changed, 282 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index 579e02ae2..507f57bab 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Je ne suis pas fier des cinq lignes qui suivent mais difficile de faire autrement pour le moment... +// I'm not proud of those five following lines but ti's hard to do with another way now #ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED #else @@ -16,6 +16,17 @@ namespace Nz { + /*! + * \fn Nz::MemoryHelper + * \brief Core functions that helps the handle of memory in the engine + */ + + /*! + * \brief Calls the operator delete on the pointer + * + * \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator delete + */ + inline void OperatorDelete(void* ptr) { #if NAZARA_CORE_MANAGE_MEMORY @@ -25,6 +36,12 @@ namespace Nz #endif } + /*! + * \brief Calls the operator new on the pointer + * + * \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator new + */ + inline void* OperatorNew(std::size_t size) { #if NAZARA_CORE_MANAGE_MEMORY @@ -34,6 +51,14 @@ namespace Nz #endif } + /*! + * \brief Constructs the object inplace + * \return Pointer to the constructed object + * + * \param ptr Pointer to raw memory allocated + * \param args Arguments for the constructor + */ + template T* PlacementNew(void* ptr, Args&&... args) { @@ -43,7 +68,7 @@ namespace Nz #include -// Si c'est nous qui avons défini la constante, alors il nous faut l'enlever (Pour éviter que le moteur entier n'en souffre) +// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine) #ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED #undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION #endif diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl index 73514dcc4..839f2564c 100644 --- a/include/Nazara/Core/MemoryStream.inl +++ b/include/Nazara/Core/MemoryStream.inl @@ -7,18 +7,36 @@ namespace Nz { + /*! + * \brief Constructs a MemoryStream object by default + */ + inline MemoryStream::MemoryStream() : Stream(StreamOption_None, OpenMode_ReadWrite), m_pos(0) { } + /*! + * \brief Constructs a MemoryStream object with a byte array + * + * \param byteArray Bytes to stream + * \param openMode Reading/writing mode for the stream + */ + inline MemoryStream::MemoryStream(ByteArray* byteArray, UInt32 openMode) : MemoryStream() { SetBuffer(byteArray, openMode); } + /*! + * \brief Gets the internal buffer + * \return Buffer of bytes + * + * \remark Produces a NazaraAssert if buffer is invalid + */ + inline ByteArray& MemoryStream::GetBuffer() { NazaraAssert(m_buffer, "Invalid buffer"); @@ -26,6 +44,13 @@ namespace Nz return *m_buffer; } + /*! + * \brief Gets the internal buffer + * \return Buffer of bytes + * + * \remark Produces a NazaraAssert if buffer is invalid + */ + inline const ByteArray& MemoryStream::GetBuffer() const { NazaraAssert(m_buffer, "Invalid buffer"); diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index db58f2299..20dc17fa8 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -15,7 +15,7 @@ #include #endif -// Le seul fichier n'ayant pas à inclure Debug.hpp +// The only file that does not need to include Debug.hpp namespace Nz { @@ -61,18 +61,43 @@ namespace Nz CRITICAL_SECTION s_mutex; #elif defined(NAZARA_PLATFORM_POSIX) pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; + #else + #error Lack of implementation: Mutex #endif } + + /*! + * \class Nz::MemoryManager + * \brief Core class that represents a manager for the memory + */ + + /*! + * \brief Constructs a MemoryManager object by default + */ MemoryManager::MemoryManager() { } + /*! + * \brief Destructs a MemoryManager object and calls Unitialize + */ + MemoryManager::~MemoryManager() { Uninitialize(); } + /*! + * \brief Allocates memory + * \return Raw memory allocated + * + * \param size Size to allocate + * \parma multi Array or not + * \param file File of the allocation + * \param line Line of the allocation in the file + */ + void* MemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line) { if (!s_initialized) @@ -147,16 +172,37 @@ namespace Nz return reinterpret_cast(ptr) + sizeof(Block); } + /*! + * \brief Enables the filling of the allocation + * + * \param allocationFilling If true, sets the rest of the allocation block to '0xFF' + */ + void MemoryManager::EnableAllocationFilling(bool allocationFilling) { s_allocationFilling = allocationFilling; } + /*! + * \brief Enables the logging of the allocation + * + * \param logAllocations If true, registers every allocation + */ + void MemoryManager::EnableAllocationLogging(bool logAllocations) { s_allocationLogging = logAllocations; } + /*! + * \brief Frees the pointer + * + * \param pointer Pointer to free + * \param multi Array or not + * + * \remark If pointer is nullptr, nothing is done + */ + void MemoryManager::Free(void* pointer, bool multi) { if (!pointer) @@ -227,37 +273,73 @@ namespace Nz #endif } + /*! + * \brief Gets the number of allocated blocks + * \return Number of allocated blocks + */ + unsigned int MemoryManager::GetAllocatedBlockCount() { return s_allocatedBlock; } + /*! + * \brief Gets the allocated size + * \return Size of total allocation + */ + std::size_t MemoryManager::GetAllocatedSize() { return s_allocatedSize; } + /*! + * \brief Gets the number of allocations + * \return Number of allocations + */ + unsigned int MemoryManager::GetAllocationCount() { return s_allocationCount; } + /*! + * \brief Checks whether the filling of allocation is enabled + * \return true if it is filling + */ + bool MemoryManager::IsAllocationFillingEnabled() { return s_allocationFilling; } + /*! + * \brief Checks whether the logging of allocation is enabled + * \return true if it is logging + */ + bool MemoryManager::IsAllocationLoggingEnabled() { return s_allocationLogging; } + /*! + * \brief Sets the next free + * + * \param file Name of the file + * \param line Line in the file + */ + void MemoryManager::NextFree(const char* file, unsigned int line) { s_nextFreeFile = file; s_nextFreeLine = line; } + /*! + * \brief Initializes the MemoryManager + */ + void MemoryManager::Initialize() { char timeStr[23]; @@ -282,12 +364,22 @@ namespace Nz s_initialized = true; } + /*! + * \brief Gets the time + * + * \param buffer Buffer to set the time in + */ + void MemoryManager::TimeInfo(char buffer[23]) { time_t currentTime = std::time(nullptr); std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime)); } + /*! + * \brief Uninitializes the MemoryManager + */ + void MemoryManager::Uninitialize() { #ifdef NAZARA_PLATFORM_WINDOWS @@ -334,5 +426,5 @@ namespace Nz } std::fclose(log); -} + } } diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index b311cd058..7940fee8a 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -10,33 +10,75 @@ namespace Nz { + /*! + * \class Nz::MemoryStream + * \brief Core class that represents a stream of memory + */ + + /*! + * \brief Clears the content of the stream + */ + void MemoryStream::Clear() { m_buffer->Clear(); m_pos = 0; } + /*! + * \brief Checks whether the stream reached the end of the stream + * \return true if cursor is at the end of the stream + */ + bool MemoryStream::EndOfStream() const { return m_pos >= m_buffer->size(); } + /*! + * \brief Gets the position of the cursor + * \return Position of the cursor + */ + UInt64 MemoryStream::GetCursorPos() const { return m_pos; } + /*! + * \brief Gets the size of the raw memory + * \return Size of the memory + */ + UInt64 MemoryStream::GetSize() const { return m_buffer->GetSize(); } + /*! + * \brief Sets the buffer for the memory stream + * + * \param byteArray Bytes to stream + * \param openMode Reading/writing mode for the stream + * + * \remark Produces a NazaraAssert if byteArray is nullptr + */ + void MemoryStream::SetBuffer(ByteArray* byteArray, UInt32 openMode) { + NazaraAssert(byteArray, "Invalid ByteArray"); + m_buffer = byteArray; m_openMode = openMode; } + /*! + * \brief Sets the position of the cursor + * \return true + * + * \param offset Offset according to the beginning of the stream + */ + bool MemoryStream::SetCursorPos(UInt64 offset) { m_pos = offset; @@ -44,11 +86,23 @@ namespace Nz return true; } + /*! + * \brief Flushes the stream + */ + void MemoryStream::FlushStream() { // Nothing to flush } + /*! + * \brief Reads blocks + * \return Number of blocks read + * + * \param buffer Preallocated buffer to contain information read + * \param size Size of the read and thus of the buffer + */ + std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size) { if (EndOfStream()) @@ -63,14 +117,26 @@ namespace Nz return readSize; } + /*! + * \brief Writes blocks + * \return Number of blocks written + * + * \param buffer Preallocated buffer containing information to write + * \param size Size of the writting and thus of the buffer + * + * \remark Produces a NazaraAssert if buffer is nullptr + */ + std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size) { std::size_t endPos = static_cast(m_pos + size); if (endPos > m_buffer->GetSize()) m_buffer->Resize(endPos); + NazaraAssert(buffer, "Invalid buffer"); + std::memcpy(m_buffer->GetBuffer() + m_pos, buffer, size); - + m_pos = endPos; return size; } diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index 77c69bcb4..a636eb9a8 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -9,6 +9,20 @@ namespace Nz { + /*! + * \class Nz::MemoryView + * \brief Core class that represents a view of the memory behaving like a stream + */ + + /*! + * \brief Constructs a MemoryView object with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + MemoryView::MemoryView(void* ptr, UInt64 size) : Stream(StreamOption_None, OpenMode_ReadWrite), m_ptr(reinterpret_cast(ptr)), @@ -17,6 +31,15 @@ namespace Nz { } + /*! + * \brief Constructs a MemoryView object with a raw memory and a size + * + * \param ptr Constant pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + MemoryView::MemoryView(const void* ptr, UInt64 size) : Stream(StreamOption_None, OpenMode_ReadOnly), m_ptr(reinterpret_cast(const_cast(ptr))), //< Okay, right, const_cast is bad, but this pointer is still read-only @@ -25,21 +48,43 @@ namespace Nz { } + /*! + * \brief Checks whether the stream reached the end of the stream + * \return true if cursor is at the end of the stream + */ + bool MemoryView::EndOfStream() const { return m_pos >= m_size; } + /*! + * \brief Gets the position of the cursor + * \return Position of the cursor + */ + UInt64 MemoryView::GetCursorPos() const { return m_pos; } + /*! + * \brief Gets the size of the raw memory + * \return Size of the memory + */ + UInt64 MemoryView::GetSize() const { return m_size; } + /*! + * \brief Sets the position of the cursor + * \return true + * + * \param offset Offset according to the beginning of the stream + */ + bool MemoryView::SetCursorPos(UInt64 offset) { m_pos = std::min(offset, m_size); @@ -47,11 +92,23 @@ namespace Nz return true; } + /*! + * \brief Flushes the stream + */ + void MemoryView::FlushStream() { // Nothing to do } + /*! + * \brief Reads blocks + * \return Number of blocks read + * + * \param buffer Preallocated buffer to contain information read + * \param size Size of the read and thus of the buffer + */ + std::size_t MemoryView::ReadBlock(void* buffer, std::size_t size) { std::size_t readSize = std::min(size, static_cast(m_size - m_pos)); @@ -63,12 +120,24 @@ namespace Nz return readSize; } + /*! + * \brief Writes blocks + * \return Number of blocks written + * + * \param buffer Preallocated buffer containing information to write + * \param size Size of the writting and thus of the buffer + * + * \remark Produces a NazaraAssert if buffer is nullptr + */ + std::size_t MemoryView::WriteBlock(const void* buffer, std::size_t size) { std::size_t endPos = static_cast(m_pos + size); if (endPos > m_size) size = m_size - m_pos; + NazaraAssert(buffer, "Invalid buffer"); + std::memcpy(&m_ptr[m_pos], buffer, size); m_pos += size; From c163d65da7a7a28a2359305084be911a6f44d785 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:29:03 +0100 Subject: [PATCH 113/229] Documentation for Thread Former-commit-id: b33bbdf473792ddcde8ffbe310722d83a1a12bcf --- include/Nazara/Core/TaskScheduler.inl | 25 +++++ include/Nazara/Core/Thread.inl | 25 +++++ include/Nazara/Core/ThreadSafety.hpp | 4 +- include/Nazara/Core/ThreadSafetyOff.hpp | 4 +- src/Nazara/Core/TaskScheduler.cpp | 50 +++++++++ src/Nazara/Core/Thread.cpp | 128 ++++++++++++++++++++++++ 6 files changed, 232 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/TaskScheduler.inl b/include/Nazara/Core/TaskScheduler.inl index b8b99ed47..ba64cfb1a 100644 --- a/include/Nazara/Core/TaskScheduler.inl +++ b/include/Nazara/Core/TaskScheduler.inl @@ -6,18 +6,43 @@ namespace Nz { + /*! + * \class Nz::TaskScheduler + * \brief Core class that represents a thread pool + */ + + /*! + * \brief Adds a task to the pending list + * + * \param function Task that the pool will execute + */ + template void TaskScheduler::AddTask(F function) { AddTaskFunctor(new FunctorWithoutArgs(function)); } + /*! + * \brief Adds a task to the pending list + * + * \param function Task that the pool will execute + * \param args Arguments of the function + */ + template void TaskScheduler::AddTask(F function, Args&&... args) { AddTaskFunctor(new FunctorWithArgs(function, std::forward(args)...)); } + /*! + * \brief Adds a task to the pending list + * + * \param function Task that the pool will execute + * \param object Object on which the method will be called + */ + template void TaskScheduler::AddTask(void (C::*function)(), C* object) { diff --git a/include/Nazara/Core/Thread.inl b/include/Nazara/Core/Thread.inl index d6c76522a..f3de4ae24 100644 --- a/include/Nazara/Core/Thread.inl +++ b/include/Nazara/Core/Thread.inl @@ -7,18 +7,43 @@ namespace Nz { + /*! + * \class Nz::Thread + * \brief Core class that represents a thread + */ + + /*! + * \brief Constructs a Thread object with a function + * + * \param function Task the thread will execute in parallel + */ + template Thread::Thread(F function) { CreateImpl(new FunctorWithoutArgs(function)); } + /*! + * \brief Constructs a Thread object with a function and its parameters + * + * \param function Task the thread will execute in parallel + * \param args Arguments of the function + */ + template Thread::Thread(F function, Args&&... args) { CreateImpl(new FunctorWithArgs(function, std::forward(args)...)); } + /*! + * \brief Constructs a Thread object with a member function and its object + * + * \param function Task the thread will execute in parallel + * \param object Object on which the method will be called + */ + template Thread::Thread(void (C::*function)(), C* object) { diff --git a/include/Nazara/Core/ThreadSafety.hpp b/include/Nazara/Core/ThreadSafety.hpp index 26b446ae6..5b1629b5b 100644 --- a/include/Nazara/Core/ThreadSafety.hpp +++ b/include/Nazara/Core/ThreadSafety.hpp @@ -2,12 +2,12 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Pas de header guard +// No header guard #include #include -// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise dans une même unité de compilation +// These macroes can change for any file which uses it in the same unit of compilation #undef NazaraLock #undef NazaraMutex #undef NazaraMutexAttrib diff --git a/include/Nazara/Core/ThreadSafetyOff.hpp b/include/Nazara/Core/ThreadSafetyOff.hpp index e6a1ce208..29c327e0d 100644 --- a/include/Nazara/Core/ThreadSafetyOff.hpp +++ b/include/Nazara/Core/ThreadSafetyOff.hpp @@ -2,9 +2,9 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Pas de header guard +// No header guard -// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise dans une même unité de compilation +// These macroes can change for any file which uses it in the same unit of compilation #undef NazaraLock #undef NazaraMutex #undef NazaraMutexAttrib diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index 27d071987..108e120b1 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -24,16 +24,39 @@ namespace Nz unsigned int s_workerCount = 0; } + /*! + * \class Nz::TaskScheduler + * \brief Core class that represents a pool of threads + * + * \remark Initialized should be called first + */ + + /*! + * \brief Gets the number of threads + * \return Number of threads, if none, the number of simulatenous threads on the processor is returned + */ + unsigned int TaskScheduler::GetWorkerCount() { return (s_workerCount > 0) ? s_workerCount : HardwareInfo::GetProcessorCount(); } + /*! + * \brief Initializes the TaskScheduler class + * \return true if everything is ok + */ + bool TaskScheduler::Initialize() { return TaskSchedulerImpl::Initialize(GetWorkerCount()); } + /*! + * \brief Runs the pending works + * + * \remark Produce a NazaraError if the class is not initialized + */ + void TaskScheduler::Run() { if (!Initialize()) @@ -49,6 +72,14 @@ namespace Nz } } + /*! + * \brief Sets the number of workers + * + * \param workerCount Number of simulatnous threads handling the tasks + * + * \remark Produce a NazaraError if the class is not initialized and NAZARA_CORE_SAFE is defined + */ + void TaskScheduler::SetWorkerCount(unsigned int workerCount) { #ifdef NAZARA_CORE_SAFE @@ -62,12 +93,22 @@ namespace Nz s_workerCount = workerCount; } + /*! + * \brief Uninitializes the TaskScheduler class + */ + void TaskScheduler::Uninitialize() { if (TaskSchedulerImpl::IsInitialized()) TaskSchedulerImpl::Uninitialize(); } + /*! + * \brief Waits for tasks to be done + * + * \remark Produce a NazaraError if the class is not initialized + */ + void TaskScheduler::WaitForTasks() { if (!Initialize()) @@ -79,6 +120,15 @@ namespace Nz TaskSchedulerImpl::WaitForTasks(); } + /*! + * \brief Adds a task on the pending list + * + * \param taskFunctor Functor represeting a task to be done + * + * \remark Produce a NazaraError if the class is not initialized + * \remark A task containing a call on this class is undefined behaviour + */ + void TaskScheduler::AddTaskFunctor(Functor* taskFunctor) { if (!Initialize()) diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index 105067baf..da01025d3 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -21,17 +21,36 @@ namespace Nz { + /*! + * \class Nz::Thread + * \brief Core class that represents a thread + */ + + /*! + * \brief Constructs a Thread object by default + */ + Thread::Thread() : m_impl(nullptr) { } + /*! + * \brief Constructs a Thread object by move semantic + * + * \param other Thread to move into this + */ + Thread::Thread(Thread&& other) noexcept : m_impl(other.m_impl) { other.m_impl = nullptr; } + /*! + * \brief Waits that the thread ends and then destroys this + */ + Thread::~Thread() { if (m_impl) @@ -42,6 +61,10 @@ namespace Nz } } + /*! + * \brief Detaches the thread + */ + void Thread::Detach() { if (m_impl) @@ -52,16 +75,32 @@ namespace Nz } } + /*! + * \brief Gets the id of the thread + * \return The identifiant of the thread (PID) + */ + Thread::Id Thread::GetId() const { return Thread::Id(m_impl); } + /*! + * \brief Checks whether the thread can be joined + * \return true if well formed and not detached + */ + bool Thread::IsJoinable() const { return m_impl != nullptr; } + /*! + * \brief Waits that the thread ends + * + * \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined + */ + void Thread::Join() { #if NAZARA_CORE_SAFE @@ -77,6 +116,16 @@ namespace Nz m_impl = nullptr; } + /*! + * \brief Moves the other thread into this + * \return A reference to this + * + * \param thread Thread to move in this + * + * \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined + * \remark And call std::terminate if no functor was assigned and NAZARA_CORE_SAFE is defined + */ + Thread& Thread::operator=(Thread&& thread) { #if NAZARA_CORE_SAFE @@ -91,16 +140,33 @@ namespace Nz return *this; } + /*! + * \brief Gets the number of simulatenous threads that can run on the same cpu + * \return The number of simulatenous threads + */ + unsigned int Thread::HardwareConcurrency() { return HardwareInfo::GetProcessorCount(); } + /*! + * \brief Makes sleep this thread + * + * \param milliseconds The number of milliseconds to sleep + */ + void Thread::Sleep(UInt32 milliseconds) { ThreadImpl::Sleep(milliseconds); } + /*! + * \brief Creates the implementation of this thread + * + * \param functor The task the thread will represent + */ + void Thread::CreateImpl(Functor* functor) { m_impl = new ThreadImpl(functor); @@ -108,41 +174,103 @@ namespace Nz /*********************************Thread::Id********************************/ + /*! + * \brief Constructs a Thread object with a thread implementation + * + * \param thread Thread implementation assigned to the thread + */ + Thread::Id::Id(ThreadImpl* thread) : m_id(thread) { } + /*! + * \brief Compares two Thread::Id + * \return true if the two thread ids are the same + * + * \param lhs First id + * \param rhs Second id + */ + bool operator==(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id == rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return false if the two thread ids are the same + * + * \param lhs First id + * \param rhs Second id + */ + bool operator!=(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id != rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is inferior to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator<(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id < rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is inferior or equal to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator<=(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id <= rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is superior to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator>(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id > rhs.m_id; } + /*! + * \brief Compares two Thread::Id + * \return true if the first thread id is superior or equal to the second one + * + * \param lhs First id + * \param rhs Second id + */ + bool operator>=(const Thread::Id& lhs, const Thread::Id& rhs) { return lhs.m_id >= rhs.m_id; } + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param id The thread id to output + */ + std::ostream& operator<<(std::ostream& o, const Nz::Thread::Id& id) { o << id.m_id; From f5400298250e7eba3433f366cf2b2ae1f1382763 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:32:17 +0100 Subject: [PATCH 114/229] Documentation for String Former-commit-id: caf1b5889604d7c2248ec88bde99a6bce0d7680f --- include/Nazara/Core/String.hpp | 12 +- include/Nazara/Core/String.inl | 42 + include/Nazara/Core/Unicode.hpp | 20 +- src/Nazara/Core/String.cpp | 1751 +++++++++++++++++++++++++++++- src/Nazara/Core/StringStream.cpp | 151 +++ src/Nazara/Core/Unicode.cpp | 58 +- 6 files changed, 1974 insertions(+), 60 deletions(-) diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index a99326bf4..70673ae8a 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -23,11 +23,11 @@ namespace Nz public: enum Flags { - None = 0x00, // Mode par défaut - CaseInsensitive = 0x01, // Insensible à la casse - HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8 - TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne - TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne + None = 0x00, // Default mode + CaseInsensitive = 0x01, // Case insensitive + HandleUtf8 = 0x02, // Considers bytes as a list of UTF-8 characters + TrimOnlyLeft = 0x04, // Trim(med), only cut the left part of the string + TrimOnlyRight = 0x08 // Trim(med), only cut the right part of the string }; String(); @@ -71,7 +71,7 @@ namespace Nz std::size_t FindAny(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; std::size_t FindAny(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; std::size_t FindLast(char character, std::intmax_t start = -1, UInt32 flags = None) const; - std::size_t FindLast(const char *string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLast(const char* string, std::intmax_t start = -1, UInt32 flags = None) const; std::size_t FindLast(const String& string, std::intmax_t start = -1, UInt32 flags = None) const; std::size_t FindLastAny(const char* string, std::intmax_t start = -1, UInt32 flags = None) const; std::size_t FindLastAny(const String& string, std::intmax_t start = -1, UInt32 flags = None) const; diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 93ff32312..40c08d315 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -7,22 +7,42 @@ namespace Nz { + /*! + * \brief Constructs a String object with a shared string by move semantic + * + * \param sharedString Shared string to move into this + */ + inline String::String(std::shared_ptr&& sharedString) : m_sharedString(std::move(sharedString)) { } + /*! + * \brief Releases the content to the string + */ + inline void String::ReleaseString() { m_sharedString = std::move(GetEmptyString()); } + /*! + * \brief Constructs a SharedString object by default + */ + inline String::SharedString::SharedString() : // Special case: empty string capacity(0), size(0) { } + /*! + * \brief Constructs a SharedString object with a size + * + * \param strSize Number of characters in the string + */ + inline String::SharedString::SharedString(std::size_t strSize) : capacity(strSize), size(strSize), @@ -31,6 +51,13 @@ namespace Nz string[strSize] = '\0'; } + /*! + * \brief Constructs a SharedString object with a size and a capacity + * + * \param strSize Number of characters in the string + * \param strCapacity Capacity in characters in the string + */ + inline String::SharedString::SharedString(std::size_t strSize, std::size_t strCapacity) : capacity(strCapacity), size(strSize), @@ -39,6 +66,14 @@ namespace Nz string[strSize] = '\0'; } + /*! + * \brief Appends the string to the hash + * \return true if hash is successful + * + * \param hash Hash to append data of the file + * \param string String to hash + */ + inline bool HashAppend(AbstractHash* hash, const String& string) { hash->Append(reinterpret_cast(string.GetConstBuffer()), string.GetSize()); @@ -48,6 +83,13 @@ namespace Nz namespace std { + /*! + * \brief Specialisation of std to hash + * \return Result of the hash + * + * \param str String to hash + */ + template<> struct hash { diff --git a/include/Nazara/Core/Unicode.hpp b/include/Nazara/Core/Unicode.hpp index 631d8f8bd..a42e88e90 100644 --- a/include/Nazara/Core/Unicode.hpp +++ b/include/Nazara/Core/Unicode.hpp @@ -18,16 +18,16 @@ namespace Nz Unicode() = delete; ~Unicode() = delete; /* - Catégorie Unicode: - -Les valeurs de 0x01 à 0x80 indiquent la catégorie. - -Les valeurs de 0x100 à 0x10000 indiquent la sous-catégorie. + Unicode category: + -Values between 0x01 and 0x80 specify the category + -Values between 0x100 and 0x10000 specify the subcategory */ enum Category : UInt16 { - // Catégorie non-reconnue par Nazara + // Category not handled by Nazara Category_NoCategory = 0, - // Lettres + // Letters Category_Letter = 0x01, // L Category_Letter_Lowercase = Category_Letter | 0x0100, // Ll Category_Letter_Modifier = Category_Letter | 0x0200, // Lm @@ -35,19 +35,19 @@ namespace Nz Category_Letter_Titlecase = Category_Letter | 0x0800, // Lt Category_Letter_Uppercase = Category_Letter | 0x1000, // Lu - // Marques + // Marks Category_Mark = 0x02, // M Category_Mark_Enclosing = Category_Mark | 0x100, // Me Category_Mark_NonSpacing = Category_Mark | 0x200, // Mn Category_Mark_SpacingCombining = Category_Mark | 0x400, // Mc - // Nombres + // Numbers Category_Number = 0x04, // N Category_Number_DecimalDigit = Category_Number | 0x100, // Nd Category_Number_Letter = Category_Number | 0x200, // Nl Category_Number_Other = Category_Number | 0x400, // No - // Autres + // Others Category_Other = 0x08, // C Category_Other_Control = Category_Other | 0x0100, // Cc Category_Other_Format = Category_Other | 0x0200, // Cf @@ -65,13 +65,13 @@ namespace Nz Category_Punctuation_Open = Category_Punctuation | 0x2000, // Ps Category_Punctuation_Other = Category_Punctuation | 0x4000, // Po - // Espacements + // Spaces Category_Separator = 0x20, // Z Category_Separator_Line = Category_Separator | 0x0100, // Zl Category_Separator_Paragraph = Category_Separator | 0x0200, // Zp Category_Separator_Space = Category_Separator | 0x0400, // Zs - // Symboles + // Symbols Category_Symbol = 0x40, // S Category_Symbol_Currency = Category_Symbol | 0x0100, // Sc Category_Symbol_Math = Category_Symbol | 0x0200, // Sm diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index daa5cb85a..74c2afe80 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -///TODO: Réécrire une bonne partie des algorithmes employés (Relu jusqu'à 3538) +///TODO: Rewrite most of used algorithms (Reread to to line 4638) #include #include @@ -23,7 +23,7 @@ namespace Nz { namespace Detail { - // Cet algorithme est inspiré de la documentation de Qt + // This algorithm is inspired by the documentation of Qt inline std::size_t GetNewSize(std::size_t newSize) { if (newSize < 20) @@ -76,11 +76,26 @@ namespace Nz } } + /*! + * \class Nz::String + * \brief Core class that represents a string + */ + + /*! + * \brief Constructs a String object by default + */ + String::String() : m_sharedString(GetEmptyString()) { } + /*! + * \brief Constructs a String object with a character + * + * \param character Single character + */ + String::String(char character) { if (character != '\0') @@ -92,6 +107,13 @@ namespace Nz m_sharedString = GetEmptyString(); } + /*! + * \brief Constructs a String object with multiple times the same character + * + * \param rep Number of repetitions of the character + * \param character Single character + */ + String::String(std::size_t rep, char character) { if (rep > 0) @@ -105,11 +127,26 @@ namespace Nz m_sharedString = GetEmptyString(); } + /*! + * \brief Constructs a String object with multiple times the same string + * + * \param rep Number of repetitions of the string + * \param string String to multiply + */ + String::String(std::size_t rep, const char* string) : String(rep, string, (string) ? std::strlen(string) : 0) { } + /*! + * \brief Constructs a String object with multiple times the same string + * + * \param rep Number of repetitions of the string + * \param string String to multiply + * \param length Length of the string + */ + String::String(std::size_t rep, const char* string, std::size_t length) { std::size_t totalSize = rep*length; @@ -125,16 +162,36 @@ namespace Nz m_sharedString = GetEmptyString(); } + /*! + * \brief Constructs a String object with multiple times the same string + * + * \param rep Number of repetitions of the string + * \param string String to multiply + */ + String::String(std::size_t rep, const String& string) : String(rep, string.GetConstBuffer(), string.GetSize()) { } + /*! + * \brief Constructs a String object with a "C string" + * + * \param string String to represent + */ + String::String(const char* string) : String(string, (string) ? std::strlen(string) : 0) { } + /*! + * \brief Constructs a String object with a "C string" + * + * \param string String to represent + * \param length Length of the string + */ + String::String(const char* string, std::size_t length) { if (length > 0) @@ -146,31 +203,80 @@ namespace Nz m_sharedString = GetEmptyString(); } + /*! + * \brief Constructs a String object which is a copy of another + * + * \param string String to copy + */ + String::String(const std::string& string) : String(string.c_str(), string.size()) { } + /*! + * \brief Appends the character to the string + * \return A reference to this + * + * \param character Single character + * + * \see Insert + */ + String& String::Append(char character) { return Insert(m_sharedString->size, character); } + /*! + * \brief Appends the "C string" to the string + * \return A reference to this + * + * \param string String to add + * + * \see Insert + */ + String& String::Append(const char* string) { return Insert(m_sharedString->size, string); } + /*! + * \brief Appends the "C string" to the string + * \return A reference to this + * + * \param string String to add + * \param length Size of the string + * + * \see Insert + */ + String& String::Append(const char* string, std::size_t length) { return Insert(m_sharedString->size, string, length); } + /*! + * \brief Appends the string to the string + * \return A reference to this + * + * \param string String to add + * + * \see Insert + */ + String& String::Append(const String& string) { return Insert(m_sharedString->size, string); } + /*! + * \brief Clears the content of the string + * + * \param keepBuffer Should the buffer be kept + */ + void String::Clear(bool keepBuffer) { if (keepBuffer) @@ -182,21 +288,63 @@ namespace Nz ReleaseString(); } + /*! + * \Brief Checks whether the string contains the character + * \return true if found in the string + * + * \param character Single character + * \param start Index to begin the research + * \param flags Flag for the look up + * + * \see Find + */ + bool String::Contains(char character, std::intmax_t start, UInt32 flags) const { return Find(character, start, flags) != npos; } + /*! + * \Brief Checks whether the string contains the "C string" + * \return true if found in the string + * + * \param string String to search + * \param start Index to begin the research + * \param flags Flag for the look up + * + * \see Find + */ + bool String::Contains(const char* string, std::intmax_t start, UInt32 flags) const { return Find(string, start, flags) != npos; } + /*! + * \Brief Checks whether the string contains the string + * \return true if found in the string + * + * \param string String to search + * \param start Index to begin the research + * \param flags Flag for the look up + * + * \see Find + */ + bool String::Contains(const String& string, std::intmax_t start, UInt32 flags) const { return Find(string, start, flags) != npos; } + /*! + * \brief Counts the number of occurrences in the string + * \return Number of occurrences + * + * \param character Single character + * \param start Index to begin the research + * \param flags Flag for the look up + */ + unsigned int String::Count(char character, std::intmax_t start, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) @@ -234,6 +382,15 @@ namespace Nz return count; } + /*! + * \brief Counts the number of occurrences in the string + * \return Number of occurrences + * + * \param string String to count + * \param start Index to begin the research + * \param flags Flag for the look up + */ + unsigned int String::Count(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -331,11 +488,29 @@ namespace Nz return count; } + /*! + * \brief Counts the number of occurrences in the string + * \return Number of occurrences + * + * \param string String to count + * \param start Index to begin the research + * \param flags Flag for the look up + */ + unsigned int String::Count(const String& string, std::intmax_t start, UInt32 flags) const { return Count(string.GetConstBuffer(), start, flags); } + /*! + * \brief Counts the number of occurrences of any characters in the list in the string + * \return Number of occurrences + * + * \param string String to match + * \param start Index to begin the research + * \param flags Flag for the look up + */ + unsigned int String::CountAny(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -424,11 +599,30 @@ namespace Nz return count; } + /*! + * \brief Counts the number of occurrences of any characters in the list in the string + * \return Number of occurrences + * + * \param string String to match + * \param start Index to begin the research + * \param flags Flag for the look up + */ + unsigned int String::CountAny(const String& string, std::intmax_t start, UInt32 flags) const { return CountAny(string.GetConstBuffer(), start, flags); } + /*! + * \brief Checks whether the string ends with the character + * \return true if it the case + * + * \param character Single character + * \param flags Flag for the look up + * + * \see StartsWith + */ + bool String::EndsWith(char character, UInt32 flags) const { if (m_sharedString->size == 0) @@ -437,14 +631,35 @@ namespace Nz if (flags & CaseInsensitive) return Detail::ToLower(m_sharedString->string[m_sharedString->size-1]) == Detail::ToLower(character); else - return m_sharedString->string[m_sharedString->size-1] == character; // character == '\0' sera toujours faux + return m_sharedString->string[m_sharedString->size-1] == character; // character == '\0' will always be false } + /*! + * \brief Checks whether the string ends with the "C string" + * \return true if it the case + * + * \param string String to match + * \param flags Flag for the look up + * + * \see StartsWith + */ + bool String::EndsWith(const char* string, UInt32 flags) const { return EndsWith(string, std::strlen(string), flags); } + /*! + * \brief Checks whether the string ends with the "C string" + * \return true if it the case + * + * \param string String to match + * \param length Size of the string + * \param flags Flag for the look up + * + * \see StartsWith + */ + bool String::EndsWith(const char* string, std::size_t length, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0 || length > m_sharedString->size) @@ -461,11 +676,30 @@ namespace Nz return std::strcmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; } + /*! + * \brief Checks whether the string ends with the string + * \return true if it the case + * + * \param string String to match + * \param flags Flag for the look up + * + * \see StartsWith + */ + bool String::EndsWith(const String& string, UInt32 flags) const { return EndsWith(string.GetConstBuffer(), string.m_sharedString->size, flags); } + /*! + * \brief Finds the first index of the character in the string + * \return Index in the string + * + * \param character Single character + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::Find(char character, std::intmax_t start, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) @@ -501,6 +735,15 @@ namespace Nz } } + /*! + * \brief Finds the first index of the "C string" in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::Find(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -591,11 +834,29 @@ namespace Nz return npos; } + /*! + * \brief Finds the first index of the string in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::Find(const String& string, std::intmax_t start, UInt32 flags) const { return Find(string.GetConstBuffer(), start, flags); } + /*! + * \brief Finds the first index of any characters in the list in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindAny(const char* string, std::intmax_t start, UInt32 flags) const { if (m_sharedString->size == 0 || !string || !string[0]) @@ -674,11 +935,29 @@ namespace Nz return npos; } + /*! + * \brief Finds the first index of any characters in the list in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindAny(const String& string, std::intmax_t start, UInt32 flags) const { return FindAny(string.GetConstBuffer(), start, flags); } + /*! + * \brief Finds the last index of the character in the string + * \return Index in the string + * + * \param character Single character + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLast(char character, std::intmax_t start, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) @@ -716,6 +995,15 @@ namespace Nz return npos; } + /*! + * \brief Finds the last index of the "C string" in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLast(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -728,14 +1016,14 @@ namespace Nz if (pos >= m_sharedString->size) return npos; - ///Algo 1.FindLast#3 (Taille du pattern inconnue) + ///Algo 1.FindLast#3 (Size of the pattern unknown) const char* ptr = &m_sharedString->string[pos]; if (flags & CaseInsensitive) { if (flags & HandleUtf8) { if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + utf8::unchecked::prior(ptr); // We ensure to have one pointer pointing to the begin of the character utf8::unchecked::iterator it(ptr); const char* t = string; @@ -824,6 +1112,15 @@ namespace Nz return npos; } + /*! + * \brief Finds the last index of the string in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLast(const String& string, std::intmax_t start, UInt32 flags) const { if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) @@ -843,9 +1140,9 @@ namespace Nz { if (flags & HandleUtf8) { - ///Algo 1.FindLast#3 (Itérateur non-adapté) + ///Algo 1.FindLast#3 (Iterator non-adapted) if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + utf8::unchecked::prior(ptr); // We ensure to have one pointer pointing to the begin of the character utf8::unchecked::iterator it(ptr); const char* t = string.GetConstBuffer(); @@ -878,7 +1175,7 @@ namespace Nz } else { - ///Algo 1.FindLast#4 (Taille du pattern connue) + ///Algo 1.FindLast#4 (Size of the pattern unknown) char c = Detail::ToLower(string.m_sharedString->string[string.m_sharedString->size-1]); for (;;) { @@ -904,7 +1201,7 @@ namespace Nz } else { - ///Algo 1.FindLast#4 (Taille du pattern connue) + ///Algo 1.FindLast#4 (Size of the pattern known) for (;;) { if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) @@ -930,6 +1227,15 @@ namespace Nz return npos; } + /*! + * \brief Finds the last index of any characters in the list in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLastAny(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -1016,11 +1322,29 @@ namespace Nz return npos; } + /*! + * \brief Finds the last index of any characters in the list in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLastAny(const String& string, std::intmax_t start, UInt32 flags) const { return FindLastAny(string.GetConstBuffer(), start, flags); } + /*! + * \brief Finds the last word in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLastWord(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -1033,19 +1357,19 @@ namespace Nz if (pos >= m_sharedString->size) return npos; - ///Algo 2.FindLastWord#1 (Taille du pattern inconnue) + ///Algo 2.FindLastWord#1 (Size of the pattern unknown) const char* ptr = &m_sharedString->string[pos]; if (flags & HandleUtf8) { if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + utf8::unchecked::prior(ptr); // We ensure to have a pointer pointing to the beginning of the string utf8::unchecked::iterator it(ptr); if (flags & CaseInsensitive) { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string; // utf8(::unchecked)::next affects the iterator on argument UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); do { @@ -1087,7 +1411,7 @@ namespace Nz } else { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string; // utf8(::unchecked)::next affects the iterator on argument UInt32 c = utf8::unchecked::next(t); do { @@ -1204,6 +1528,15 @@ namespace Nz return npos; } + /*! + * \brief Finds the last word in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindLastWord(const String& string, std::intmax_t start, UInt32 flags) const { if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) @@ -1222,13 +1555,13 @@ namespace Nz if (flags & HandleUtf8) { if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + utf8::unchecked::prior(ptr); // We ensure to have a pointer pointing to the beginning of the string utf8::unchecked::iterator it(ptr); if (flags & CaseInsensitive) { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affects the iterator on argument UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); do { @@ -1270,7 +1603,7 @@ namespace Nz } else { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affects the iterator on argument UInt32 c = utf8::unchecked::next(t); do { @@ -1313,7 +1646,7 @@ namespace Nz } else { - ///Algo 2.FindLastWord#2 (Taille du pattern connue) + ///Algo 2.FindLastWord#2 (Size of the pattern known) if (flags & CaseInsensitive) { char c = Detail::ToLower(string.m_sharedString->string[string.m_sharedString->size-1]); @@ -1380,6 +1713,15 @@ namespace Nz return npos; } + /*! + * \brief Finds the first word in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindWord(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -1392,18 +1734,18 @@ namespace Nz if (pos >= m_sharedString->size) return npos; - ///Algo 3.FindWord#3 (Taille du pattern inconnue) + ///Algo 3.FindWord#3 (Size of the pattern unknown) const char* ptr = m_sharedString->string.get(); if (flags & HandleUtf8) { if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + utf8::unchecked::prior(ptr); // We ensure to have one pointer pointing to the begin of the character utf8::unchecked::iterator it(ptr); if (flags & CaseInsensitive) { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string; // utf8(::unchecked)::next affects the iterator on argument UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); do @@ -1443,7 +1785,7 @@ namespace Nz } else { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string; // utf8(::unchecked)::next affects the iterator on argument UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); do @@ -1552,6 +1894,15 @@ namespace Nz return npos; } + /*! + * \brief Finds the first word in the string + * \return Index in the string + * + * \param string String to match + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::FindWord(const String& string, std::intmax_t start, UInt32 flags) const { if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) @@ -1567,15 +1918,15 @@ namespace Nz char* ptr = m_sharedString->string.get(); if (flags & HandleUtf8) { - ///Algo 3.FindWord#3 (Itérateur trop lent pour #2) + ///Algo 3.FindWord#3 (Iterator too slow for #2) if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + utf8::unchecked::prior(ptr); // We ensure to have one pointer pointing to the begin of the character utf8::unchecked::iterator it(ptr); if (flags & CaseInsensitive) { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affects the iterator on argument UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); do @@ -1615,7 +1966,7 @@ namespace Nz } else { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affects the iterator on argument UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); do @@ -1656,7 +2007,7 @@ namespace Nz } else { - ///Algo 3.FindWord#2 (Taille du pattern connue) + ///Algo 3.FindWord#2 (Size of the pattern known) if (flags & CaseInsensitive) { char c = Detail::ToLower(string.m_sharedString->string[0]); @@ -1693,7 +2044,7 @@ namespace Nz { while ((ptr = std::strstr(ptr, string.GetConstBuffer())) != nullptr) { - // Si le mot est bien isolé + // If the word is really alone if ((ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || std::isspace(*(ptr+m_sharedString->size)))) return ptr - m_sharedString->string.get(); @@ -1705,6 +2056,11 @@ namespace Nz return npos; } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + */ + char* String::GetBuffer() { EnsureOwnership(); @@ -1712,31 +2068,61 @@ namespace Nz return m_sharedString->string.get(); } + /*! + * \brief Gets the capacity of the string + * \return Capacity of the string + */ + std::size_t String::GetCapacity() const { return m_sharedString->capacity; } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + */ + const char* String::GetConstBuffer() const { return m_sharedString->string.get(); } + /*! + * \brief Gets the length of the string + * \return Length of the string with UTF-8 awareness + */ + std::size_t String::GetLength() const { return utf8::distance(m_sharedString->string.get(), &m_sharedString->string[m_sharedString->size]); } + /*! + * \brief Gets the size of the string + * \return Size of the string without UTF-8 awareness + */ + std::size_t String::GetSize() const { return m_sharedString->size; } + /*! + * \brief Gets the std::string corresponding + * \return String in UTF-8 + */ + std::string String::GetUtf8String() const { return std::string(m_sharedString->string.get(), m_sharedString->size); } + /*! + * \brief Gets the std::string corresponding + * \return String in UTF-16 + */ + std::u16string String::GetUtf16String() const { if (m_sharedString->size == 0) @@ -1750,6 +2136,11 @@ namespace Nz return str; } + /*! + * \brief Gets the std::string corresponding + * \return String in UTF-32 + */ + std::u32string String::GetUtf32String() const { if (m_sharedString->size == 0) @@ -1763,6 +2154,11 @@ namespace Nz return str; } + /*! + * \brief Gets the std::wstring corresponding + * \return String in Wide + */ + std::wstring String::GetWideString() const { static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "wchar_t size is not supported"); @@ -1772,7 +2168,7 @@ namespace Nz std::wstring str; str.reserve(m_sharedString->size); - if (sizeof(wchar_t) == 4) // Je veux du static_if :( + if (sizeof(wchar_t) == 4) // I want a static_if :( utf8::utf8to32(begin(), end(), std::back_inserter(str)); else { @@ -1791,6 +2187,14 @@ namespace Nz return str; } + /*! + * \brief Gets the word until next separator + * \return Word string + * + * \param start Index to begin the search + * \param flags Flag for the look up + */ + String String::GetWord(unsigned int index, UInt32 flags) const { std::size_t startPos = GetWordPosition(index, flags); @@ -1828,6 +2232,14 @@ namespace Nz return SubString(startPos, endPos); } + /*! + * \brief Gets the word position + * \return Position of the beginning of the word + * + * \param start Index to begin the search + * \param flags Flag for the look up + */ + std::size_t String::GetWordPosition(unsigned int index, UInt32 flags) const { if (m_sharedString->size == 0) @@ -1878,16 +2290,41 @@ namespace Nz return npos; } + /*! + * \brief Inserts the character into the string + * \return A reference to this + * + * \param pos Position in the string + * \param character Single character + */ + String& String::Insert(std::intmax_t pos, char character) { return Insert(pos, &character, 1); } + /*! + * \brief Inserts the "C string" into the string + * \return A reference to this + * + * \param pos Position in the string + * \param string String to add + */ + String& String::Insert(std::intmax_t pos, const char* string) { return Insert(pos, string, std::strlen(string)); } + /*! + * \brief Inserts the "C string" into the string + * \return A reference to this + * + * \param pos Position in the string + * \param string String to add + * \param length Size of the string + */ + String& String::Insert(std::intmax_t pos, const char* string, std::size_t length) { if (length == 0) @@ -1898,7 +2335,7 @@ namespace Nz std::size_t start = std::min(pos, m_sharedString->size); - // Si le buffer est déjà suffisamment grand + // If buffer is already big enough if (m_sharedString->capacity >= m_sharedString->size + length) { EnsureOwnership(); @@ -1933,21 +2370,49 @@ namespace Nz return *this; } + /*! + * \brief Inserts the string into the string + * \return A reference to this + * + * \param pos Position in the string + * \param string String to add + */ + String& String::Insert(std::intmax_t pos, const String& string) { return Insert(pos, string.GetConstBuffer(), string.m_sharedString->size); } + /*! + * \brief Checks whether the string is empty + * \return true if string is empty + */ + bool String::IsEmpty() const { return m_sharedString->size == 0; } + /*! + * \brief Checks whether the string is null + * \return true if string is null + */ + bool String::IsNull() const { return m_sharedString.get() == GetEmptyString().get(); } + /*! + * \brief Checks whether the string is a number + * \return true if string is a number + * + * \param base Base of the number + * \param flags Flag for the look up + * + * \remark Produces a NazaraError if base is not in [2, 36( with NAZARA_CORE_SAFE defined + */ + bool String::IsNumber(UInt8 base, UInt32 flags) const { #if NAZARA_CORE_SAFE @@ -2010,6 +2475,13 @@ namespace Nz return true; } + /*! + * \brief Checks whether the string matches the pattern + * \return true if string matches + * + * \param pattern Pattern to search + */ + bool String::Match(const char* pattern) const { if (m_sharedString->size == 0 || !pattern) @@ -2057,37 +2529,91 @@ namespace Nz return !*pattern; } + /*! + * \brief Checks whether the string matches the pattern + * \return true if string matches + * + * \param pattern Pattern to search + */ + bool String::Match(const String& pattern) const { return Match(pattern.m_sharedString->string.get()); } + /*! + * \brief Prepends the character to the string + * \return A reference to this + * + * \param character Single character + * + * \see Insert + */ + String& String::Prepend(char character) { return Insert(0, character); } + /*! + * \brief Prepends the "C string" to the string + * \return A reference to this + * + * \param string String to add + * + * \see Insert + */ + String& String::Prepend(const char* string) { return Insert(0, string); } + /*! + * \brief Prepends the "C string" to the string + * \return A reference to this + * + * \param string String to add + * \param length Size of the string + * + * \see Insert + */ + String& String::Prepend(const char* string, std::size_t length) { return Insert(0, string, length); } + /*! + * \brief Prepends the string to the string + * \return A reference to this + * + * \param string String to add + * + * \see Insert + */ + String& String::Prepend(const String& string) { return Insert(0, string); } + /*! + * \brief Replaces the old character by the new one + * \return Number of changes + * + * \param oldCharacter Pattern to find + * \param newCharacter Pattern to change for + * \param start Index to begin the search + * \param flags Flag for the look up + */ + unsigned int String::Replace(char oldCharacter, char newCharacter, std::intmax_t start, UInt32 flags) { if (oldCharacter == '\0' || oldCharacter == newCharacter) return 0; - if (newCharacter == '\0') // Dans ce cas, il faut passer par un algorithme plus complexe + if (newCharacter == '\0') // In this case, we must use a more advanced algorithm return Replace(String(oldCharacter), String(), start); if (start < 0) @@ -2146,11 +2672,33 @@ namespace Nz return count; } + /*! + * \brief Replaces the old "C string" by the new one + * \return Number of changes + * + * \param oldCharacter Pattern to find + * \param newCharacter Pattern to change for + * \param start Index to begin the search + * \param flags Flag for the look up + */ + unsigned int String::Replace(const char* oldString, const char* replaceString, std::intmax_t start, UInt32 flags) { return Replace(oldString, std::strlen(oldString), replaceString, std::strlen(replaceString), start, flags); } + /*! + * \brief Replaces the old "C string" by the new one + * \return Number of changes + * + * \param oldCharacter Pattern to find + * \param oldLength Length of the old string + * \param newCharacter Pattern to change for + * \param Length of the new string + * \param start Index to begin the search + * \param flags Flag for the look up + */ + unsigned int String::Replace(const char* oldString, std::size_t oldLength, const char* replaceString, std::size_t replaceLength, std::intmax_t start, UInt32 flags) { if (oldLength == 0) @@ -2168,7 +2716,7 @@ namespace Nz { bool found = false; - // Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide + // If no size change is necessary, we can thus use a quicker algorithm while ((pos = Find(oldString, pos, flags)) != npos) { if (!found) @@ -2183,10 +2731,10 @@ namespace Nz ++count; } } - else ///TODO: Algorithme de remplacement sans changement de buffer (si replaceLength < oldLength) + else ///TODO: Replacement algorithm without changing the buffer (if replaceLength < oldLength) { std::size_t newSize = m_sharedString->size + Count(oldString)*(replaceLength - oldLength); - if (newSize == m_sharedString->size) // Alors c'est que Count(oldString) == 0 + if (newSize == m_sharedString->size) // Then it's the fact that Count(oldString) == 0 return 0; auto newString = std::make_shared(newSize); @@ -2217,18 +2765,40 @@ namespace Nz return count; } + /*! + * \brief Replaces the old string by the new one + * \return Number of changes + * + * \param oldCharacter Pattern to find + * \param newCharacter Pattern to change for + * \param start Index to begin the search + * \param flags Flag for the look up + */ + unsigned int String::Replace(const String& oldString, const String& replaceString, std::intmax_t start, UInt32 flags) { return Replace(oldString.GetConstBuffer(), oldString.m_sharedString->size, replaceString.GetConstBuffer(), replaceString.m_sharedString->size, start, flags); } + /*! + * \brief Replaces the old characters in the list by the new one + * \return Number of changes + * + * \param oldCharacters Pattern to find + * \param newCharacter Pattern to change for + * \param start Index to begin the search + * \param flags Flag for the look up + * + * \remark Does not handle UTF-8 currently + */ + unsigned int String::ReplaceAny(const char* oldCharacters, char replaceCharacter, std::intmax_t start, UInt32 flags) { - ///FIXME: Ne gère pas l'UTF-8 + ///FIXME: Does not handle UTF-8 if (!oldCharacters || !oldCharacters[0]) return 0; - /*if (replaceCharacter == '\0') // Dans ce cas, il faut passer par un algorithme plus complexe + /*if (replaceCharacter == '\0') // In this case, we must use a more advance algorithm return ReplaceAny(String(oldCharacters), String(), start);*/ if (start < 0) @@ -2454,6 +3024,14 @@ namespace Nz } */ + /*! + * \brief Reserves enough memory for the buffer size + * + * \param bufferSize Size of the buffer to allocate + * + * \remark If bufferSize is smaller than the old one, nothing is done + */ + void String::Reserve(std::size_t bufferSize) { if (m_sharedString->capacity > bufferSize) @@ -2468,6 +3046,14 @@ namespace Nz m_sharedString = std::move(newString); } + /*! + * \brief Resizes the string + * \return A reference to this + * + * \param size Target size + * \param flags Flag for the look up + */ + String& String::Resize(std::intmax_t size, UInt32 flags) { if (size == 0) @@ -2510,6 +3096,14 @@ namespace Nz return *this; } + /*! + * \brief Resize a copy of the string + * \return A copy of what would be the string resized + * + * \param size Target size + * \param flags Flag for the look up + */ + String String::Resized(std::intmax_t size, UInt32 flags) const { if (size < 0) @@ -2542,6 +3136,11 @@ namespace Nz return String(std::move(sharedStr)); } + /*! + * \brief Reverses the string + * \return A reference to this + */ + String& String::Reverse() { if (m_sharedString->size != 0) @@ -2556,6 +3155,11 @@ namespace Nz return *this; } + /*! + * \brief Reverses a copy of the string + * \return A copy of what would be the string reversed + */ + String String::Reversed() const { if (m_sharedString->size == 0) @@ -2573,6 +3177,13 @@ namespace Nz return String(std::move(sharedStr)); } + /*! + * \brief Sets the string to the character + * \return A reference to this + * + * \param character Single character + */ + String& String::Set(char character) { if (character != '\0') @@ -2597,6 +3208,15 @@ namespace Nz return *this; } + + /*! + * \brief Sets the string with multiple times the same character + * \return A reference to this + * + * \param rep Number of repetitions of the character + * \param character Single character + */ + String& String::Set(std::size_t rep, char character) { if (rep > 0) @@ -2620,11 +3240,28 @@ namespace Nz return *this; } + /*! + * \brief Sets the string with multiple times the same string + * \return A reference to this + * + * \param rep Number of repetitions of the string + * \param string String to multiply + */ + String& String::Set(std::size_t rep, const char* string) { return Set(rep, string, (string) ? std::strlen(string) : 0); } + /*! + * \brief Sets the string with multiple times the same string + * \return A reference to this + * + * \param rep Number of repetitions of the string + * \param string String to multiply + * \param length Length of the string + */ + String& String::Set(std::size_t rep, const char* string, std::size_t length) { std::size_t totalSize = rep*length; @@ -2650,16 +3287,39 @@ namespace Nz return *this; } + /*! + * \brief Sets the string with multiple times the same string + * \return A reference to this + * + * \param rep Number of repetitions of the string + * \param string String to multiply + */ + String& String::Set(std::size_t rep, const String& string) { return Set(rep, string.GetConstBuffer(), string.m_sharedString->size); } + /*! + * \brief Sets the string with other "C string" + * \return A reference to this + * + * \param string String to copy + */ + String& String::Set(const char* string) { return Set(string, (string) ? std::strlen(string) : 0); } + /*! + * \brief Sets the string with other "C string" + * \return A reference to this + * + * \param string String to represent + * \param length Length of the string + */ + String& String::Set(const char* string, std::size_t length) { if (length > 0) @@ -2682,11 +3342,25 @@ namespace Nz return *this; } + /*! + * \brief Sets the string with a std::string + * \return A reference to this + * + * \param string String to copy + */ + String& String::Set(const std::string& string) { return Set(string.data(), string.size()); } + /*! + * \brief Sets the string with other string + * \return A reference to this + * + * \param string String to copy + */ + String& String::Set(const String& string) { m_sharedString = string.m_sharedString; @@ -2694,6 +3368,13 @@ namespace Nz return *this; } + /*! + * \brief Sets the string by move semantic + * \return A reference to this + * + * \param string String to move + */ + String& String::Set(String&& string) noexcept { std::swap(m_sharedString, string.m_sharedString); @@ -2701,6 +3382,13 @@ namespace Nz return *this; } + /*! + * \brief Simplifies a copy of the string + * \return A copy of what would be the string simplified + * + * \param flags Flag for the look up + */ + String String::Simplified(UInt32 flags) const { if (m_sharedString->size == 0) @@ -2763,11 +3451,28 @@ namespace Nz return String(std::move(newString)); } + /*! + * \brief Simplifies the string + * \return A reference to this + * + * \param flags Flag for the look up + */ + String& String::Simplify(UInt32 flags) { return Set(Simplified(flags)); } + /*! + * \brief Splits the string into others + * \return The number of splits + * + * \param result Resulting tokens + * \param separation Separation character + * \param start Index for the beginning of the search + * \param flags Flag for the look up + */ + unsigned int String::Split(std::vector& result, char separation, std::intmax_t start, UInt32 flags) const { if (separation == '\0' || m_sharedString->size == 0) @@ -2800,11 +3505,32 @@ namespace Nz return result.size(); } + /*! + * \brief Splits the string into others + * \return The number of splits + * + * \param result Resulting tokens + * \param separation Separation string + * \param start Index for the beginning of the search + * \param flags Flag for the look up + */ + unsigned int String::Split(std::vector& result, const char* separation, std::intmax_t start, UInt32 flags) const { return Split(result, separation, std::strlen(separation), start, flags); } + /*! + * \brief Splits the string into others + * \return The number of splits + * + * \param result Resulting tokens + * \param separation Separation String + * \param length Length of the string + * \param start Index for the beginning of the search + * \param flags Flag for the look up + */ + unsigned int String::Split(std::vector& result, const char* separation, std::size_t length, std::intmax_t start, UInt32 flags) const { if (m_sharedString->size == 0) @@ -2848,11 +3574,31 @@ namespace Nz return result.size()-oldSize; } + /*! + * \brief Splits the string into others + * \return The number of splits + * + * \param result Resulting tokens + * \param separation Separation string + * \param start Index for the beginning of the search + * \param flags Flag for the look up + */ + unsigned int String::Split(std::vector& result, const String& separation, std::intmax_t start, UInt32 flags) const { return Split(result, separation.m_sharedString->string.get(), separation.m_sharedString->size, start, flags); } + /*! + * \brief Splits the string into others + * \return The number of splits + * + * \param result Resulting tokens + * \param separation List of characters of separation + * \param start Index for the beginning of the search + * \param flags Flag for the look up + */ + unsigned int String::SplitAny(std::vector& result, const char* separations, std::intmax_t start, UInt32 flags) const { if (m_sharedString->size == 0) @@ -2884,11 +3630,31 @@ namespace Nz return result.size()-oldSize; } + /*! + * \brief Splits the string into others + * \return The number of splits + * + * \param result Resulting tokens + * \param separation List of characters of separation + * \param start Index for the beginning of the search + * \param flags Flag for the look up + */ + unsigned int String::SplitAny(std::vector& result, const String& separations, std::intmax_t start, UInt32 flags) const { return SplitAny(result, separations.m_sharedString->string.get(), start, flags); } + /*! + * \brief Checks whether the string begins with the character + * \return true if it the case + * + * \param character Single character + * \param flags Flag for the look up + * + * \see EndsWith + */ + bool String::StartsWith(char character, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) @@ -2900,6 +3666,16 @@ namespace Nz return m_sharedString->string[0] == character; } + /*! + * \brief Checks whether the string begins with the "C string" + * \return true if it the case + * + * \param string String to match + * \param flags Flag for the look up + * + * \see EndsWith + */ + bool String::StartsWith(const char* string, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) @@ -2960,6 +3736,16 @@ namespace Nz return false; } + /*! + * \brief Checks whether the string begins with the string + * \return true if it the case + * + * \param string String to match + * \param flags Flag for the look up + * + * \see EndsWith + */ + bool String::StartsWith(const String& string, UInt32 flags) const { if (string.m_sharedString->size == 0) @@ -3009,6 +3795,14 @@ namespace Nz return false; } + /*! + * \brief Returns a sub string of the string + * \return SubString + * + * \param startPos Index for the beginning of the search + * \param endPos Index for the end of the search + */ + String String::SubString(std::intmax_t startPos, std::intmax_t endPos) const { if (startPos < 0) @@ -3035,6 +3829,17 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Returns a sub string of the string from a character + * \return SubString + * + * \param charater Pattern to find + * \param startPos Index for the beginning of the search + * \param fromLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringFrom(char character, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { if (character == '\0') @@ -3054,11 +3859,34 @@ namespace Nz return SubString(pos + ((include) ? 0 : 1)); } + /*! + * \brief Returns a sub string of the string from a string + * \return SubString + * + * \param string Pattern to find + * \param startPos Index for the beginning of the search + * \param fromLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringFrom(const char* string, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { return SubStringFrom(string, std::strlen(string), startPos, fromLast, include, flags); } + /*! + * \brief Returns a sub string of the string from a string + * \return SubString + * + * \param string Pattern to find + * \param length Size of the string + * \param startPos Index for the beginning of the search + * \param fromLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringFrom(const char* string, std::size_t length, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { std::size_t pos; @@ -3075,11 +3903,33 @@ namespace Nz return SubString(pos + ((include) ? 0 : length)); } + /*! + * \brief Returns a sub string of the string from a string + * \return SubString + * + * \param string Pattern to find + * \param startPos Index for the beginning of the search + * \param fromLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringFrom(const String& string, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { return SubStringFrom(string.GetConstBuffer(), string.m_sharedString->size, startPos, fromLast, include, flags); } + /*! + * \brief Returns a sub string of the string up to a character + * \return SubString + * + * \param charater Pattern to find + * \param startPos Index for the beginning of the search + * \param toLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringTo(char character, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { if (character == '\0') @@ -3099,11 +3949,34 @@ namespace Nz return SubString(0, pos+((include) ? 1 : 0)-1); } + /*! + * \brief Returns a sub string of the string up to a string + * \return SubString + * + * \param string Pattern to find + * \param startPos Index for the beginning of the search + * \param toLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringTo(const char* string, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { return SubStringTo(string, std::strlen(string), startPos, toLast, include, flags); } + /*! + * \brief Returns a sub string of the string up to a string + * \return SubString + * + * \param string Pattern to find + * \param length Size of the string + * \param startPos Index for the beginning of the search + * \param toLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringTo(const char* string, std::size_t length, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { std::size_t pos; @@ -3120,16 +3993,41 @@ namespace Nz return SubString(0, pos+((include) ? length : 0)-1); } + /*! + * \brief Returns a sub string of the string up to a string + * \return SubString + * + * \param string Pattern to find + * \param startPos Index for the beginning of the search + * \param toLast beginning by the end + * \param include Include the character + * \param flags Flag for the look up + */ + String String::SubStringTo(const String& string, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { return SubStringTo(string.GetConstBuffer(), string.m_sharedString->size, startPos, toLast, include, flags); } + /*! + * \brief Swaps the content with the other string + * + * \param str Other string to swap with + */ + void String::Swap(String& str) { std::swap(m_sharedString, str.m_sharedString); } + /*! + * \brief Converts the string to boolean + * \return true if successful + * + * \param value Boolean to convert to + * \param flags Flag for the look up + */ + bool String::ToBool(bool* value, UInt32 flags) const { if (m_sharedString->size == 0) @@ -3150,7 +4048,7 @@ namespace Nz else { if (flags & CaseInsensitive) - word = word.ToLower(); // Les mots identifiés sont en ASCII, inutile de passer le flag unicode + word = word.ToLower(); // The identified words are in ASCII, no use of Unicode flag if (word == "true") { @@ -3169,6 +4067,14 @@ namespace Nz return true; } + /*! + * \brief Converts the string to double + * \return true if successful + * + * \param value Double to convert to + * \param flags Flag for the look up + */ + bool String::ToDouble(double* value) const { if (m_sharedString->size == 0) @@ -3180,6 +4086,14 @@ namespace Nz return true; } + /*! + * \brief Converts the string to integer + * \return true if successful + * + * \param value Integer to convert to + * \param flags Flag for the look up + */ + bool String::ToInteger(long long* value, UInt8 base) const { if (value) @@ -3193,6 +4107,13 @@ namespace Nz return IsNumber(base); } + /*! + * \brief Converts the string to lower + * \return Lower string + * + * \param flags Flag for the look up + */ + String String::ToLower(UInt32 flags) const { if (m_sharedString->size == 0) @@ -3225,6 +4146,13 @@ namespace Nz } } + /*! + * \brief Converts the string to upper + * \return Upper string + * + * \param flags Flag for the look up + */ + String String::ToUpper(UInt32 flags) const { if (m_sharedString->size == 0) @@ -3257,16 +4185,38 @@ namespace Nz } } + /*! + * \brief Trims the string + * \return A reference to this + * + * \param flags Flag for the look up + */ + String& String::Trim(UInt32 flags) { return Set(Trimmed(flags)); } + /*! + * \brief Trims the string from a character + * \return A reference to this + * + * \param character Character to suppress + * \param flags Flag for the look up + */ + String& String::Trim(char character, UInt32 flags) { return Set(Trimmed(character, flags)); } + /*! + * \brief Trims a copy of the string + * \return A copy of what would be the string trimmed + * + * \param flags Flag for the look up + */ + String String::Trimmed(UInt32 flags) const { if (m_sharedString->size == 0) @@ -3331,6 +4281,14 @@ namespace Nz return SubString(startPos, endPos); } + /*! + * \brief Trims a copy of the string from a character + * \return A copy of what would be the string trimmed + * + * \param character Character to suppress + * \param flags Flag for the look up + */ + String String::Trimmed(char character, UInt32 flags) const { if (m_sharedString->size == 0) @@ -3383,31 +4341,67 @@ namespace Nz return SubString(startPos, endPos); } + /*! + * \brief Returns an iterator pointing to the beginning of the string + * \return beginning of the string + */ + char* String::begin() { return m_sharedString->string.get(); } + /*! + * \brief Returns an iterator pointing to the beginning of the string + * \return beginning of the string + */ + const char* String::begin() const { return m_sharedString->string.get(); } + /*! + * \brief Returns an iterator pointing to the end of the string + * \return End of the string + */ + char* String::end() { return &m_sharedString->string[m_sharedString->size]; } + /*! + * \brief Returns an iterator pointing to the end of the string + * \return End of the string + */ + const char* String::end() const { return &m_sharedString->string[m_sharedString->size]; } + /*! + * \brief Pushed the character to the front of the string + * + * \param c Single character + * + * \see Prepend + */ + void String::push_front(char c) { Prepend(c); } + /*! + * \brief Pushed the character to the back of the string + * + * \param c Single character + * + * \see Append + */ + void String::push_back(char c) { Append(c); @@ -3434,11 +4428,25 @@ namespace Nz } */ + /*! + * \brief Converts the string to std::string + * \return std::string representation + */ + String::operator std::string() const { return std::string(m_sharedString->string.get(), m_sharedString->size); } + /*! + * \brief Gets the ith character in the string + * \return A reference to the character + * + * \param pos Index of the character + * + * \remark If pos is greather than the size, Resize is called + */ + char& String::operator[](std::size_t pos) { EnsureOwnership(); @@ -3449,6 +4457,15 @@ namespace Nz return m_sharedString->string[pos]; } + /*! + * \brief Gets the ith character in the string + * \return The character + * + * \param pos Index of the character + * + * \remark Produces a NazaraError if pos is greather than the size + */ + char String::operator[](std::size_t pos) const { #if NAZARA_CORE_SAFE @@ -3462,31 +4479,73 @@ namespace Nz return m_sharedString->string[pos]; } + /*! + * \brief Assigns the string to the character + * \return A reference to this + * + * \param character Single character + */ + String& String::operator=(char character) { return Set(character); } + /*! + * \brief Assigns the string with other "C string" + * \return A reference to this + * + * \param string String to copy + */ + String& String::operator=(const char* string) { return Set(string); } + /*! + * \brief Assigns the string with a std::string + * \return A reference to this + * + * \param string String to copy + */ + String& String::operator=(const std::string& string) { return Set(string); } + /*! + * \brief Assigns the string with other string + * \return A reference to this + * + * \param string String to copy + */ + String& String::operator=(const String& string) { return Set(string); } + /*! + * \brief Assigns the string by move semantic + * \return A reference to this + * + * \param string String to move + */ + String& String::operator=(String&& string) noexcept { return Set(string); } + /*! + * \brief Concatenates the character to the string + * \return String which is the result of the concatenation + * + * \param character Single character + */ + String String::operator+(char character) const { if (character == '\0') @@ -3499,6 +4558,13 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Concatenates the "C string" to the string + * \return String which is the result of the concatenation + * + * \param string String to add + */ + String String::operator+(const char* string) const { if (!string || !string[0]) @@ -3518,6 +4584,13 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Concatenates the std::string to the string + * \return String which is the result of the concatenation + * + * \param string String to add + */ + String String::operator+(const std::string& string) const { if (string.empty()) @@ -3533,6 +4606,13 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Concatenates the string to the string + * \return String which is the result of the concatenation + * + * \param string String to add + */ + String String::operator+(const String& string) const { if (string.m_sharedString->size == 0) @@ -3548,26 +4628,61 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Concatenates the character to this string + * \return A reference to this + * + * \param character Single character + */ + String& String::operator+=(char character) { return Insert(m_sharedString->size, character); } + /*! + * \brief Concatenates the "C string" to this string + * \return A reference to this + * + * \param string String to add + */ + String& String::operator+=(const char* string) { return Insert(m_sharedString->size, string); } + /*! + * \brief Concatenates the std::string to this string + * \return A reference to this + * + * \param string String to add + */ + String& String::operator+=(const std::string& string) { return Insert(m_sharedString->size, string.c_str(), string.size()); } + /*! + * \brief Concatenates the string to this string + * \return A reference to this + * + * \param string String to add + */ + String& String::operator+=(const String& string) { return Insert(m_sharedString->size, string); } + /*! + * \brief Checks whether the string is equal to the character + * \return true if it is the case + * + * \param character Single character + */ + bool String::operator==(char character) const { if (m_sharedString->size == 0) @@ -3579,6 +4694,13 @@ namespace Nz return m_sharedString->string[0] == character; } + /*! + * \brief Checks whether the string is equal to the "C string" + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator==(const char* string) const { if (m_sharedString->size == 0) @@ -3590,6 +4712,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string) == 0; } + /*! + * \brief Checks whether the string is equal to the std::string + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator==(const std::string& string) const { if (m_sharedString->size == 0 || string.empty()) @@ -3601,6 +4730,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string.c_str()) == 0; } + /*! + * \brief Checks whether the string is equal to the character + * \return false if it is the case + * + * \param character Single character + */ + bool String::operator!=(char character) const { if (m_sharedString->size == 0) @@ -3615,6 +4751,13 @@ namespace Nz return m_sharedString->string[0] != character; } + /*! + * \brief Checks whether the string is equal to the "C string" + * \return false if it is the case + * + * \param string String to compare + */ + bool String::operator!=(const char* string) const { if (m_sharedString->size == 0) @@ -3626,6 +4769,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string) != 0; } + /*! + * \brief Checks whether the string is equal to the std::string + * \return false if it is the case + * + * \param string String to compare + */ + bool String::operator!=(const std::string& string) const { if (m_sharedString->size == 0 || string.empty()) @@ -3637,6 +4787,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string.c_str()) != 0; } + /*! + * \brief Checks whether the string is less than the character + * \return true if it is the case + * + * \param character Single character + */ + bool String::operator<(char character) const { if (character == '\0') @@ -3648,6 +4805,13 @@ namespace Nz return m_sharedString->string[0] < character; } + /*! + * \brief Checks whether the string is less than the "C string" + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator<(const char* string) const { if (!string || !string[0]) @@ -3659,6 +4823,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string) < 0; } + /*! + * \brief Checks whether the string is less than the std::string + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator<(const std::string& string) const { if (string.empty()) @@ -3670,6 +4841,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string.c_str()) < 0; } + /*! + * \brief Checks whether the string is less or equal than the character + * \return true if it is the case + * + * \param character Single character + */ + bool String::operator<=(char character) const { if (m_sharedString->size == 0) @@ -3681,6 +4859,13 @@ namespace Nz return m_sharedString->string[0] < character || (m_sharedString->string[0] == character && m_sharedString->size == 1); } + /*! + * \brief Checks whether the string is less or equal than the "C string" + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator<=(const char* string) const { if (m_sharedString->size == 0) @@ -3692,6 +4877,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string) <= 0; } + /*! + * \brief Checks whether the string is less or equal than the std::string + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator<=(const std::string& string) const { if (m_sharedString->size == 0) @@ -3703,6 +4895,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string.c_str()) <= 0; } + /*! + * \brief Checks whether the string is greather than the character + * \return true if it is the case + * + * \param character Single character + */ + bool String::operator>(char character) const { if (m_sharedString->size == 0) @@ -3714,6 +4913,13 @@ namespace Nz return m_sharedString->string[0] > character; } + /*! + * \brief Checks whether the string is greather than the "C string" + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator>(const char* string) const { if (m_sharedString->size == 0) @@ -3725,6 +4931,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string) > 0; } + /*! + * \brief Checks whether the string is greather than the std::string + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator>(const std::string& string) const { if (m_sharedString->size == 0) @@ -3736,6 +4949,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string.c_str()) > 0; } + /*! + * \brief Checks whether the string is greather or equal than the character + * \return true if it is the case + * + * \param character Single character + */ + bool String::operator>=(char character) const { if (character == '\0') @@ -3747,6 +4967,13 @@ namespace Nz return m_sharedString->string[0] > character || (m_sharedString->string[0] == character && m_sharedString->size == 1); } + /*! + * \brief Checks whether the string is greather or equal than the "C string" + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator>=(const char* string) const { if (!string || !string[0]) @@ -3758,6 +4985,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string) >= 0; } + /*! + * \brief Checks whether the string is greather or equal than the std::string + * \return true if it is the case + * + * \param string String to compare + */ + bool String::operator>=(const std::string& string) const { if (string.empty()) @@ -3769,6 +5003,13 @@ namespace Nz return std::strcmp(GetConstBuffer(), string.c_str()) >= 0; } + /*! + * \brief Converts the boolean to string + * \return String representation of the boolean + * + * \param boolean Boolean value + */ + String String::Boolean(bool boolean) { std::size_t size = (boolean) ? 4 : 5; @@ -3779,6 +5020,14 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Lexicographically compares the string + * \return The expected result + * + * \param first First string to use for comparison + * \parma second Second string to use for comparison + */ + int String::Compare(const String& first, const String& second) { if (first.m_sharedString->size == 0) @@ -3790,6 +5039,13 @@ namespace Nz return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Float value + */ + String String::Number(float number) { std::ostringstream oss; @@ -3799,6 +5055,13 @@ namespace Nz return String(oss.str()); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Double value + */ + String String::Number(double number) { std::ostringstream oss; @@ -3808,6 +5071,13 @@ namespace Nz return String(oss.str()); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Long double value + */ + String String::Number(long double number) { std::ostringstream oss; @@ -3817,56 +5087,143 @@ namespace Nz return String(oss.str()); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Signed char value + * \param radix Base of the number + */ + String String::Number(signed char number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Unsigned char value + * \param radix Base of the number + */ + String String::Number(unsigned char number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Short value + * \param radix Base of the number + */ + String String::Number(short number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Unsigned short value + * \param radix Base of the number + */ + String String::Number(unsigned short number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Int value + * \param radix Base of the number + */ + String String::Number(int number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Unsigned int value + * \param radix Base of the number + */ + String String::Number(unsigned int number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Long value + * \param radix Base of the number + */ + String String::Number(long number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Unsigned long value + * \param radix Base of the number + */ + String String::Number(unsigned long number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Long long value + * \param radix Base of the number + */ + String String::Number(long long number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the number to string + * \return String representation of the number + * + * \param number Unsigned long long value + * \param radix Base of the number + */ + String String::Number(unsigned long long number, UInt8 radix) { return NumberToString(number, radix); } + /*! + * \brief Converts the pointer to string + * \return String representation of the pointer + * + * \param ptr Pointer to represent + */ + String String::Pointer(const void* ptr) { const std::size_t capacity = sizeof(void*)*2 + 2; @@ -3877,6 +5234,13 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Converts the unicode point to string + * \return String representation of the unicode point + * + * \param character Unicode point + */ + String String::Unicode(char32_t character) { if (character == '\0') @@ -3898,11 +5262,25 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Converts the unicode "C string" to string + * \return String representation of the unicode "C string" + * + * \param u8String String in UTF-8 + */ + String String::Unicode(const char* u8String) { return String(u8String); } + /*! + * \brief Converts the unicode "C string" to string + * \return String representation of the unicode "C string" + * + * \param u16String String in UTF-16 + */ + String String::Unicode(const char16_t* u16String) { if (!u16String || !u16String[0]) @@ -3914,7 +5292,7 @@ namespace Nz count++; while (*++ptr); - count *= 2; // On s'assure d'avoir la place suffisante + count *= 2; // We ensure to have enough place auto str = std::make_shared(count); @@ -3926,6 +5304,13 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Converts the unicode "C string" to string + * \return String representation of the unicode "C string" + * + * \param u32String String in UTF-32 + */ + String String::Unicode(const char32_t* u32String) { if (!u32String || !u32String[0]) @@ -3953,6 +5338,13 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Converts the unicode "C string" to string + * \return String representation of the unicode "C string" + * + * \param wString String in Wide + */ + String String::Unicode(const wchar_t* wString) { if (!wString || !wString[0]) @@ -3980,6 +5372,14 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Inputs the stream into the string + * \return A reference to the stream + * + * \param is Stream to get information from + * \param str String to set value + */ + std::istream& operator>>(std::istream& is, String& str) { str.Clear(); @@ -4004,6 +5404,14 @@ namespace Nz return is; } + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param str The string to output + */ + std::ostream& operator<<(std::ostream& os, const String& str) { if (str.IsEmpty()) @@ -4012,6 +5420,14 @@ namespace Nz return operator<<(os, str.m_sharedString->string.get()); } + /*! + * \brief Concatenates the character to the string + * \return String which is the result of the concatenation + * + * \param character Single character + * \param string String in the right hand side + */ + String operator+(char character, const String& string) { if (character == '\0') @@ -4027,6 +5443,14 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Concatenates the "C string" to the string + * \return String which is the result of the concatenation + * + * \param string String to add + * \param string String in the right hand side + */ + String operator+(const char* string, const String& nstring) { if (!string || !string[0]) @@ -4045,6 +5469,14 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Concatenates the std::string to the string + * \return String which is the result of the concatenation + * + * \param string String to add + * \param string String in the right hand side + */ + String operator+(const std::string& string, const String& nstring) { if (string.empty()) @@ -4062,6 +5494,14 @@ namespace Nz return String(std::move(str)); } + /*! + * \brief Checks whether the first string is equal to the second string + * \return true if it is the case + * + * \param first String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator==(const String& first, const String& second) { if (first.m_sharedString->size == 0 || second.m_sharedString->size == 0) @@ -4076,11 +5516,27 @@ namespace Nz return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()) == 0; } + /*! + * \brief Checks whether the first string is equal to the second string + * \return false if it is the case + * + * \param first String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator!=(const String& first, const String& second) { return !operator==(first, second); } + /*! + * \brief Checks whether the first string is less than the second string + * \return true if it is the case + * + * \param first String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator<(const String& first, const String& second) { if (second.m_sharedString->size == 0) @@ -4092,111 +5548,285 @@ namespace Nz return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()) < 0; } + /*! + * \brief Checks whether the first string is less or equal than the second string + * \return true if it is the case + * + * \param first String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator<=(const String& first, const String& second) { return !operator<(second, first); } + /*! + * \brief Checks whether the first string is greather than the second string + * \return true if it is the case + * + * \param first String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator>(const String& first, const String& second) { return second < first; } + /*! + * \brief Checks whether the first string is greather or equal than the second string + * \return true if it is the case + * + * \param first String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator>=(const String& first, const String& second) { return !operator<(first, second); } + /*! + * \brief Checks whether the string is equal to the character + * \return true if it is the case + * + * \param character Single character in left hand side + * \param second String to compare in right hand side + */ + bool operator==(char character, const String& nstring) { return nstring == character; } + /*! + * \brief Checks whether the string is equal to the "C string" + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator==(const char* string, const String& nstring) { return nstring == string; } + /*! + * \brief Checks whether the string is equal to the std::string + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator==(const std::string& string, const String& nstring) { return nstring == string; } + /*! + * \brief Checks whether the string is equal to the character + * \return false if it is the case + * + * \param character Single character in left hand side + * \param second String to compare in right hand side + */ + bool operator!=(char character, const String& nstring) { return !operator==(character, nstring); } + /*! + * \brief Checks whether the string is equal to the "C string" + * \return false if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator!=(const char* string, const String& nstring) { return !operator==(string, nstring); } + /*! + * \brief Checks whether the string is equal to the std::string + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator!=(const std::string& string, const String& nstring) { return !operator==(string, nstring); } + /*! + * \brief Checks whether the string is less than the character + * \return true if it is the case + * + * \param character Single character in left hand side + * \param second String to compare in right hand side + */ + bool operator<(char character, const String& nstring) { return nstring > character; } + /*! + * \brief Checks whether the string is less than the "C string" + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator<(const char* string, const String& nstring) { return nstring > string; } + /*! + * \brief Checks whether the string is less than the std::string + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator<(const std::string& string, const String& nstring) { return nstring > string; } + /*! + * \brief Checks whether the string is less or equal than the character + * \return true if it is the case + * + * \param character Single character in left hand side + * \param second String to compare in right hand side + */ + bool operator<=(char character, const String& nstring) { return !operator<(nstring, String(character)); } + /*! + * \brief Checks whether the string is less or equal than the "C string" + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator<=(const char* string, const String& nstring) { return !operator<(nstring, string); } + /*! + * \brief Checks whether the string is less or equal than the std::string + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator<=(const std::string& string, const String& nstring) { return !operator<(nstring, string); } + /*! + * \brief Checks whether the string is greather than the character + * \return true if it is the case + * + * \param character Single character in left hand side + * \param second String to compare in right hand side + */ + bool operator>(char character, const String& nstring) { return nstring < character; } + /*! + * \brief Checks whether the string is greather than the "C string" + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator>(const char* string, const String& nstring) { return nstring < string; } + /*! + * \brief Checks whether the string is greather than the std::string + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator>(const std::string& string, const String& nstring) { return nstring < string; } + /*! + * \brief Checks whether the string is greather or equal than the character + * \return true if it is the case + * + * \param character Single character in left hand side + * \param second String to compare in right hand side + */ + bool operator>=(char character, const String& nstring) { return !operator<(character, nstring); } + /*! + * \brief Checks whether the string is greather or equal than the "C string" + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator>=(const char* string, const String& nstring) { return !operator<(string, nstring); } + /*! + * \brief Checks whether the string is greather or equal than the std::string + * \return true if it is the case + * + * \param string String to compare in left hand side + * \param second String to compare in right hand side + */ + bool operator>=(const std::string& string, const String& nstring) { return !operator<(string, nstring); } + /*! + * \brief Ensures the ownership of the string + * + * \param discardContent Should discard the content + */ + void String::EnsureOwnership(bool discardContent) { if (!m_sharedString) @@ -4212,12 +5842,25 @@ namespace Nz } } + /*! + * \brief Gets the empty string + * \return A reference to the empty string + */ + const std::shared_ptr& String::GetEmptyString() { static auto emptyString = std::make_shared(); return emptyString; } + /*! + * \brief Serializes the string + * \return true if successful + * + * \param context Context of serialization + * \param string String to serialize + */ + bool Serialize(SerializationContext& context, const String& string) { if (!Serialize(context, string.GetSize())) @@ -4226,6 +5869,14 @@ namespace Nz return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize(); } + /*! + * \brief Unserializes the string + * \return true if successful + * + * \param context Context of unserialization + * \param string String to unserialize + */ + bool Unserialize(SerializationContext& context, String* string) { UInt32 size; @@ -4241,6 +5892,14 @@ namespace Nz namespace std { + /*! + * \brief Gets the line from the input stream + * \return A reference to the stream + * + * \param is Input stream to get information from + * \param str String to set + */ + istream& getline(istream& is, Nz::String& str) { str.Clear(); @@ -4248,7 +5907,7 @@ namespace std char c; for (;;) - { + { is.get(c); if (c != '\n' && c != '\0') str += c; @@ -4259,6 +5918,15 @@ namespace std return is; } + /*! + * \brief Gets the line from the input stream + * \return A reference to the stream + * + * \param is Input stream to get information from + * \param str String to set + * \param delim Delimitor defining the end + */ + istream& getline(istream& is, Nz::String& str, char delim) { str.Clear(); @@ -4277,6 +5945,13 @@ namespace std return is; } + /*! + * \brief Swaps two strings, specialisation of std + * + * \param lhs First string + * \param rhs Second string + */ + void swap(Nz::String& lhs, Nz::String& rhs) { lhs.Swap(rhs); diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index 2c2a8db24..a76dc9d86 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -7,17 +7,37 @@ namespace Nz { + /*! + * \class Nz::StringStream + * \brief Core class that represents a stream of strings + */ + + /*! + * \brief Constructs a StringStream object by default + */ + StringStream::StringStream() : m_bufferSize(0) { } + /*! + * \brief Constructs a StringStream object with a string + * + * \param str First value of the stream + */ + StringStream::StringStream(const String& str) : m_bufferSize(str.GetSize()) { m_strings.push_back(str); } + /*! + * \brief Gives a string representation + * \return A string representation of the object where every objects of the stream has been converted with Nz::String + */ + String StringStream::ToString() const { String string; @@ -29,6 +49,13 @@ namespace Nz return string; } + /*! + * \brief Adds the representation of the boolean + * \return A reference to this + * + * \param boolean Boolean value + */ + StringStream& StringStream::operator<<(bool boolean) { m_strings.push_back(String::Boolean(boolean)); @@ -37,6 +64,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the short + * \return A reference to this + * + * \param number Short value + */ + StringStream& StringStream::operator<<(short number) { m_strings.push_back(String::Number(number)); @@ -45,6 +79,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the unsigned short + * \return A reference to this + * + * \param number Short value + */ + StringStream& StringStream::operator<<(unsigned short number) { m_strings.push_back(String::Number(number)); @@ -53,6 +94,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the int + * \return A reference to this + * + * \param number Int value + */ + StringStream& StringStream::operator<<(int number) { m_strings.push_back(String::Number(number)); @@ -61,6 +109,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the unsigned int + * \return A reference to this + * + * \param number Int value + */ + StringStream& StringStream::operator<<(unsigned int number) { m_strings.push_back(String::Number(number)); @@ -69,6 +124,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the long + * \return A reference to this + * + * \param number Long value + */ + StringStream& StringStream::operator<<(long number) { m_strings.push_back(String::Number(number)); @@ -77,6 +139,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the unsigned long + * \return A reference to this + * + * \param number Long value + */ + StringStream& StringStream::operator<<(unsigned long number) { m_strings.push_back(String::Number(number)); @@ -85,6 +154,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the long long + * \return A reference to this + * + * \param number Long long value + */ + StringStream& StringStream::operator<<(long long number) { m_strings.push_back(String::Number(number)); @@ -93,6 +169,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the unsigned long long + * \return A reference to this + * + * \param number Long long value + */ + StringStream& StringStream::operator<<(unsigned long long number) { m_strings.push_back(String::Number(number)); @@ -101,6 +184,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the float + * \return A reference to this + * + * \param number Float value + */ + StringStream& StringStream::operator<<(float number) { m_strings.push_back(String::Number(number)); @@ -109,6 +199,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the double + * \return A reference to this + * + * \param number Double value + */ + StringStream& StringStream::operator<<(double number) { m_strings.push_back(String::Number(number)); @@ -117,6 +214,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the long double + * \return A reference to this + * + * \param number Long double value + */ + StringStream& StringStream::operator<<(long double number) { m_strings.push_back(String::Number(number)); @@ -125,6 +229,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the char + * \return A reference to this + * + * \param character Char value + */ + StringStream& StringStream::operator<<(char character) { m_strings.push_back(String(character)); @@ -133,6 +244,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the unsigned char + * \return A reference to this + * + * \param character Char value + */ + StringStream& StringStream::operator<<(unsigned char character) { m_strings.push_back(String(static_cast(character))); @@ -141,6 +259,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the const char* + * \return A reference to this + * + * \param string String value + */ + StringStream& StringStream::operator<<(const char* string) { m_strings.push_back(string); @@ -149,6 +274,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the std::string + * \return A reference to this + * + * \param string String value + */ + StringStream& StringStream::operator<<(const std::string& string) { m_strings.push_back(string); @@ -157,6 +289,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the Nz::String + * \return A reference to this + * + * \param string String value + */ + StringStream& StringStream::operator<<(const String& string) { m_strings.push_back(string); @@ -165,6 +304,13 @@ namespace Nz return *this; } + /*! + * \brief Adds the representation of the pointer + * \return A reference to this + * + * \param ptr Pointer value + */ + StringStream& StringStream::operator<<(const void* ptr) { m_strings.push_back(String::Pointer(ptr)); @@ -173,6 +319,11 @@ namespace Nz return *this; } + /*! + * \brief Converts this to Nz::String + * \return The string representation of the stream + */ + StringStream::operator String() const { return ToString(); diff --git a/src/Nazara/Core/Unicode.cpp b/src/Nazara/Core/Unicode.cpp index c5b0d6917..9168e855e 100644 --- a/src/Nazara/Core/Unicode.cpp +++ b/src/Nazara/Core/Unicode.cpp @@ -11,20 +11,32 @@ namespace Nz { struct Character { - UInt16 category; // Le type du caractère - UInt8 direction; // Le sens de lecure du caractère - UInt32 lowerCase; // Le caractère correspondant en minuscule - UInt32 titleCase; // Le caractère correspondant en titre - UInt32 upperCase; // Le caractère correspondant en majuscule + UInt16 category; // The type of the character + UInt8 direction; // The reading way of the character + UInt32 lowerCase; // The corresponding lower character + UInt32 titleCase; // The corresponding title character + UInt32 upperCase; // The corresponding upper character }; } #include -#else // Implémentation supportant la table ASCII +#else // Implementation handling ASCII table namespace Nz { + /*! + * \class Nz::Unicode + * \brief Core class that represents a Unicode character + */ + + /*! + * \brief Gets the category of the character + * \return Unicode category + * + * \param character Character to get assignated category + */ + Unicode::Category Unicode::GetCategory(char32_t character) { switch (character) @@ -188,6 +200,13 @@ namespace Nz return Category_NoCategory; } + /*! + * \brief Gets the direction of reading of the character + * \return Unicode direction + * + * \param character Character to get assignated direction + */ + Unicode::Direction Unicode::GetDirection(char32_t character) { switch (character) @@ -347,6 +366,15 @@ namespace Nz return Direction_Boundary_Neutral; } + /*! + * \brief Gets the lower case of the character + * \return Unicode lower + * + * \param character Character to get assignated lower case + * + * \remark Only handling ASCII + */ + char32_t Unicode::GetLowercase(char32_t character) { if (character >= 'A' && character <= 'Z') @@ -355,11 +383,29 @@ namespace Nz return character; } + /*! + * \brief Gets the title case of the character + * \return Unicode title + * + * \param character Character to get assignated title case + * + * \remark Only handling ASCII + */ + char32_t Unicode::GetTitlecase(char32_t character) { return GetUppercase(character); } + /*! + * \brief Gets the upper case of the character + * \return Unicode upper + * + * \param character Character to get assignated upper case + * + * \remark Only handling ASCII + */ + char32_t Unicode::GetUppercase(char32_t character) { if (character >= 'a' && character <= 'z') From d34055302370bd356bc21b8949f2b83271ba999b Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:32:59 +0100 Subject: [PATCH 115/229] Documentation for ByteArray and ByteStream Former-commit-id: 4d2d0de93562077e030b4304b57f6c95b32185b5 --- include/Nazara/Core/ByteArray.inl | 419 +++++++++++++++++++++++++++++ include/Nazara/Core/ByteStream.inl | 101 +++++++ src/Nazara/Core/ByteArray.cpp | 13 + src/Nazara/Core/ByteStream.cpp | 61 +++++ 4 files changed, 594 insertions(+) diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 1597758fd..2a8ab59a8 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -6,59 +6,141 @@ namespace Nz { + /*! + * \brief Constructs a ByteArray object with a reserved size + * + * \param n Space reserved + */ + inline ByteArray::ByteArray(size_type n) : m_array() { m_array.reserve(n); } + /*! + * \brief Constructs a ByteArray object with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param n Size that can be accessed + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + inline ByteArray::ByteArray(const void* buffer, size_type n) : m_array(static_cast(buffer), static_cast(buffer) + n) { } + /*! + * \brief Constructs a ByteArray object with n times the same value + * + * \param n Number of repetitions + * \param value Value to repeat + */ + inline ByteArray::ByteArray(size_type n, const value_type value) : m_array(n, value) { } + /*! + * \brief Constructs a ByteArray object from two iterators + * + * \param first First iterator + * \param last Second iterator + */ + template ByteArray::ByteArray(InputIterator first, InputIterator last) : m_array(first, last) { } + /*! + * \brief Appends the content of raw memory + * + * \param ptr Constant pointer to raw memory + * \param n Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Append(const void* buffer, size_type n) { return Insert(end(), static_cast(buffer), static_cast(buffer) + n); } + /*! + * \brief Appends another array of bytes + * + * \param other ByteArray to add + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Append(const ByteArray& other) { return Insert(end(), other.begin(), other.end()); } + /*! + * \brief Assigns this with n times the same value + * + * \param n Number of repetitions + * \param value Value to repeat + */ + inline void ByteArray::Assign(size_type n, value_type value) { m_array.assign(n, value); } + /*! + * \brief Assigns this with the content between two iterators + * + * \param first First iterator + * \param last Second iterator + */ + template void ByteArray::Assign(InputIterator first, InputIterator last) { m_array.assign(first, last); } + /*! + * \brief Gets last element + * \return A reference to last element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::reference ByteArray::Back() { return m_array.back(); } + /*! + * \brief Gets last element + * \return A constant reference to last element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::const_reference ByteArray::Back() const { return m_array.back(); } + /*! + * \brief Clears the content of the string + * + * \param keepBuffer Should the buffer be kept + */ + inline void ByteArray::Clear(bool keepBuffer) { m_array.clear(); @@ -66,142 +148,326 @@ namespace Nz m_array.shrink_to_fit(); } + /*! + * \brief Erases an element from the byte array + * + * \param pos Iterator to the element + */ + inline ByteArray::iterator ByteArray::Erase(const_iterator pos) { return m_array.erase(pos); } + /*! + * \brief Erases the elements between the two pointers from the byte array + * + * \param first First iterator + * \param last Second iterator + */ + inline ByteArray::iterator ByteArray::Erase(const_iterator first, const_iterator last) { return m_array.erase(first, last); } + /*! + * \brief Gets first element + * \return A reference to first element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::reference ByteArray::Front() { return m_array.front(); } + /*! + * \brief Gets first element + * \return A constant reference to first element + * + * \remark If ByteArray is empty, behaviour is undefined + */ + inline ByteArray::const_reference ByteArray::Front() const { return m_array.front(); } + /*! + * \brief Gets the internal allocator of the byte array + * \return Allocator + */ + inline ByteArray::allocator_type ByteArray::GetAllocator() const { return m_array.get_allocator(); } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + */ + inline ByteArray::pointer ByteArray::GetBuffer() { return m_array.data(); } + /*! + * \brief Gets the capacity of the byte array + * \return Capacity of the byte array + */ + inline ByteArray::size_type ByteArray::GetCapacity() const noexcept { return m_array.capacity(); } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + */ + inline ByteArray::const_pointer ByteArray::GetConstBuffer() const { return m_array.data(); } + /*! + * \brief Gets the maximal size supported by the byte array + * \return Biggest size handled + */ + inline ByteArray::size_type ByteArray::GetMaxSize() const noexcept { return m_array.max_size(); } + /*! + * \brief Gets the size of the byte array + * \return Size of the byte array + */ + inline ByteArray::size_type ByteArray::GetSize() const noexcept { return m_array.size(); } + /*! + * \brief Returns a sub byte array of the byte array + * \return Sub byte array + * + * \param startPos First iterator + * \param endPos Second iterator + */ + inline ByteArray ByteArray::GetSubArray(const_iterator startPos, const_iterator endPos) const { return ByteArray(startPos, endPos); } + /*! + * \brief Inserts the content of raw memory at the iterator position + * + * \param pos Iterator to the position + * \param buffer Constant pointer to raw memory + * \param n Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const void* buffer, size_type n) { return m_array.insert(pos, static_cast(buffer), static_cast(buffer) + n); } + /*! + * \brief Inserts the content of another byte array at the iterator position + * + * \param pos Iterator to the position + * \param other Other byte array + */ + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const ByteArray& other) { return m_array.insert(pos, other.begin(), other.end()); } + /*! + * \brief Inserts n times the same value at the iterator position + * + * \param pos Iterator to the position + * \param n Number of repetitions + * \param value Value to repeat + */ + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte) { return m_array.insert(pos, n, byte); } + /*! + * \brief Inserts the content from two iterators at the iterator position + * + * \param pos Iterator to the position + * \param first First iterator + * \param last Second iterator + */ + template ByteArray::iterator ByteArray::Insert(const_iterator pos, InputIterator first, InputIterator last) { return m_array.insert(pos, first, last); } + /*! + * \brief Checks whether the byte array is empty + * \return true if byte array is empty + */ + inline bool ByteArray::IsEmpty() const noexcept { return m_array.empty(); } + /*! + * \brief Erases the last element + * + * \remark If byte array is empty, the behaviour is undefined + */ + inline void ByteArray::PopBack() { Erase(end() - 1); } + /*! + * \brief Erases the first element + * + * \remark If byte array is empty, the behaviour is undefined + */ + inline void ByteArray::PopFront() { Erase(begin()); } + /*! + * \brief Prepends the content of raw memory + * + * \param ptr Constant pointer to raw memory + * \param n Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Prepend(const void* buffer, size_type n) { return Insert(begin(), buffer, n); } + /*! + * \brief Prepends another array of bytes + * + * \param other ByteArray to add + * + * \see Insert + */ + inline ByteArray::iterator ByteArray::Prepend(const ByteArray& other) { return Insert(begin(), other); } + /*! + * \brief Pushes the byte at the end + * + * \param byte Byte to add + */ + inline void ByteArray::PushBack(const value_type byte) { m_array.push_back(byte); } + /*! + * \brief Pushes the byte at the beginning + * + * \param byte Byte to add + */ + inline void ByteArray::PushFront(const value_type byte) { m_array.insert(begin(), 1, byte); } + /*! + * \brief Reserves enough memory for the buffer size + * + * \param bufferSize Size of the buffer to allocate + * + * \remark If bufferSize is smaller than the old one, nothing is done + */ + inline void ByteArray::Reserve(size_type bufferSize) { m_array.reserve(bufferSize); } + /*! + * \brief Resizes the string + * \return A reference to this + * + * \param newSize Target size + */ + inline void ByteArray::Resize(size_type newSize) { m_array.resize(newSize); } + /*! + * \brief Resizes the string + * \return A reference to this + * + * \param newSize Target size + * \param byte Byte to add if newSize is greather than actual size + */ + inline void ByteArray::Resize(size_type newSize, const value_type byte) { m_array.resize(newSize, byte); } + /*! + * \brief Releases the excedent memory + */ + inline void ByteArray::ShrinkToFit() { m_array.shrink_to_fit(); } + /*! + * \brief Swaps the content with the other byte array + * + * \param other Other byte array to swap with + */ + inline void ByteArray::Swap(ByteArray& other) { m_array.swap(other.m_array); } + /*! + * \brief Gives a string representation in base 16 + * \return String in base 16 + */ + inline String ByteArray::ToHex() const { std::size_t length = m_array.size() * 2; @@ -213,76 +479,153 @@ namespace Nz return hexOutput; } + /*! + * \brief Gives a string representation + * \return String where each byte is converted to char + */ + inline String ByteArray::ToString() const { return String(reinterpret_cast(GetConstBuffer()), GetSize()); } + /*! + * \brief Returns an iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::iterator ByteArray::begin() noexcept { return m_array.begin(); } + /*! + * \brief Returns an iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_iterator ByteArray::begin() const noexcept { return m_array.begin(); } + /*! + * \brief Returns a constant iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_iterator ByteArray::cbegin() const noexcept { return m_array.cbegin(); } + /*! + * \brief Returns a constant iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::const_iterator ByteArray::cend() const noexcept { return m_array.cend(); } + /*! + * \brief Returns a constant reversed iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_reverse_iterator ByteArray::crbegin() const noexcept { return m_array.crbegin(); } + /*! + * \brief Returns a constant reversed iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::const_reverse_iterator ByteArray::crend() const noexcept { return m_array.crend(); } + /*! + * \brief Checks whether the byte array is empty + * \return true if byte array is empty + */ + inline bool ByteArray::empty() const noexcept { return m_array.empty(); } + /*! + * \brief Returns an iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::iterator ByteArray::end() noexcept { return m_array.end(); } + /*! + * \brief Returns an iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::const_iterator ByteArray::end() const noexcept { return m_array.end(); } + /*! + * \brief Returns a reversed iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::reverse_iterator ByteArray::rbegin() noexcept { return m_array.rbegin(); } + /*! + * \brief Returns a reversed iterator pointing to the beggining of the string + * \return Beggining of the string + */ + inline ByteArray::const_reverse_iterator ByteArray::rbegin() const noexcept { return m_array.rbegin(); } + /*! + * \brief Returns a reversed iterator pointing to the end of the string + * \return End of the string + */ + inline ByteArray::reverse_iterator ByteArray::rend() noexcept { return m_array.rend(); } + /*! + * \brief Gets the size of the byte array + * \return Size of the byte array + */ + inline ByteArray::size_type ByteArray::size() const noexcept { return GetSize(); } + /*! + * \brief Gets the ith byte + * \return A reference to the byte at the ith position + * + * \remark Produces a NazaraAssert if pos is greather than the size + */ + inline ByteArray::reference ByteArray::operator[](size_type pos) { NazaraAssert(pos < GetSize(), "Index out of range"); @@ -290,6 +633,13 @@ namespace Nz return m_array[pos]; } + /*! + * \brief Gets the ith byte + * \return A constant reference to the byte at the ith position + * + * \remark Produces a NazaraAssert if pos is greather than the size + */ + inline ByteArray::const_reference ByteArray::operator[](size_type pos) const { NazaraAssert(pos < GetSize(), "Index out of range"); @@ -297,6 +647,13 @@ namespace Nz return m_array[pos]; } + /*! + * \brief Concatenates the byte array to another + * \return ByteArray which is the result of the concatenation + * + * \param other ByteArray to add + */ + inline ByteArray ByteArray::operator+(const ByteArray& other) const { ByteArray tmp(*this); @@ -305,6 +662,13 @@ namespace Nz return tmp; } + /*! + * \brief Concatenates the byte array to this byte array + * \return A reference to this + * + * \param other ByteArray to add + */ + inline ByteArray& ByteArray::operator+=(const ByteArray& other) { Append(other); @@ -312,31 +676,79 @@ namespace Nz return *this; } + /*! + * \brief Checks whether the first byte array is equal to the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator==(const ByteArray& rhs) const { return m_array == rhs.m_array; } + /*! + * \brief Checks whether the first byte array is equal to the second byte array + * \return false if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator!=(const ByteArray& rhs) const { return !operator==(rhs); } + /*! + * \brief Checks whether the first byte array is less than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator<(const ByteArray& rhs) const { return m_array < rhs.m_array; } + /*! + * \brief Checks whether the first byte array is less or equal than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator<=(const ByteArray& rhs) const { return m_array <= rhs.m_array; } + /*! + * \brief Checks whether the first byte array is greather than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator>(const ByteArray& rhs) const { return m_array > rhs.m_array; } + /*! + * \brief Checks whether the first byte array is greather or equal than the second byte array + * \return true if it is the case + * + * \param first ByteArray to compare in left hand side + * \param second ByteArray to compare in right hand side + */ + inline bool ByteArray::operator>=(const ByteArray& rhs) const { return m_array >= rhs.m_array; @@ -351,6 +763,13 @@ namespace Nz namespace std { + /*! + * \brief Swaps two byte arrays, specialisation of std + * + * \param lhs First byte array + * \param rhs Second byte array + */ + inline void swap(Nz::ByteArray& lhs, Nz::ByteArray& rhs) { lhs.Swap(rhs); diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl index f6e765175..83062d3ba 100644 --- a/include/Nazara/Core/ByteStream.inl +++ b/include/Nazara/Core/ByteStream.inl @@ -7,11 +7,25 @@ namespace Nz { + /*! + * \brief Constructs a ByteStream object with a stream + * + * \remark Produces a NazaraAssert if stream is invalid + */ + inline ByteStream::ByteStream(Stream* stream) { + NazaraAssert(stream, "Invalid stream"); + m_context.stream = stream; } + /*! + * \brief Constructs a ByteStream object by move semantic + * + * \param stream ByteStream to move into this + */ + inline ByteStream::ByteStream(ByteStream&& stream) : m_ownedStream(std::move(stream.m_ownedStream)), m_context(stream.m_context) @@ -19,17 +33,35 @@ namespace Nz stream.m_context.stream = nullptr; } + /*! + * \brief Destructs the object and calls FlushBits + * + * \remark Produces a NazaraWarning if flush did not work + * + * \see FlushBits + */ + inline ByteStream::~ByteStream() { if (!FlushBits()) NazaraWarning("Failed to flush bits at serializer destruction"); } + /*! + * \brief Gets the stream endianness + * \return Type of the endianness + */ + inline Endianness ByteStream::GetDataEndianness() const { return m_context.endianness; } + /*! + * \brief Gets the size of the byte stream + * \return Size of the stream + */ + inline Nz::UInt64 ByteStream::GetSize() const { if (m_context.stream) @@ -38,11 +70,21 @@ namespace Nz return 0; } + /*! + * \brief Gets the internal stream + * \return Internal stream + */ + inline Stream* ByteStream::GetStream() const { return m_context.stream; } + /*! + * \brief Flushes the stream + * \return true if flushing is successful + */ + inline bool ByteStream::FlushBits() { if (!m_context.stream) @@ -59,6 +101,14 @@ namespace Nz return true; } + /*! + * \brief Reads data + * \return Number of data read + * + * \param buffer Preallocated buffer to contain information read + * \param size Size of the read and thus of the buffer + */ + inline std::size_t ByteStream::Read(void* ptr, std::size_t size) { if (!m_context.stream) @@ -68,13 +118,29 @@ namespace Nz return m_context.stream->Read(ptr, size); } + /*! + * \brief Sets the stream endianness + * + * \param Type of the endianness + */ + inline void ByteStream::SetDataEndianness(Endianness endiannes) { m_context.endianness = endiannes; } + /*! + * \brief Sets this with a stream + * + * \param stream Stream existing + * + * \remark Produces a NazaraAssert if stream is invalid + */ + inline void ByteStream::SetStream(Stream* stream) { + NazaraAssert(stream, "Invalid stream"); + // We don't want to lose some bits.. FlushBits(); @@ -82,6 +148,16 @@ namespace Nz m_ownedStream.reset(); } + /*! + * \brief Writes data + * \return Number of data written + * + * \param buffer Preallocated buffer containing information to write + * \param size Size of the writting and thus of the buffer + * + * \remark Produces a NazaraAssert if buffer is nullptr + */ + inline void ByteStream::Write(const void* data, std::size_t size) { if (!m_context.stream) @@ -91,6 +167,15 @@ namespace Nz m_context.stream->Write(data, size); } + /*! + * \brief Outputs a data from the stream + * \return A reference to this + * + * \param value Value to unserialize + * + * \remark Produces a NazaraError if unserialization failed + */ + template ByteStream& ByteStream::operator>>(T& value) { @@ -103,6 +188,15 @@ namespace Nz return *this; } + /*! + * \brief Adds the data to the stream + * \return A reference to this + * + * \param value Value to serialize + * + * \remark Produces a NazaraError if serialization failed + */ + template ByteStream& ByteStream::operator<<(const T& value) { @@ -115,6 +209,13 @@ namespace Nz return *this; } + /*! + * \brief Moves the other byte stream into this + * \return A reference to this + * + * \param stream ByteStream to move in this + */ + inline ByteStream& ByteStream::operator=(ByteStream&& stream) { m_context = stream.m_context; diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index cc5734822..9763e6336 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -9,6 +9,19 @@ namespace Nz { + /*! + * \class Nz::ByteArray + * \brief Core class that represents an array of bytes + */ + + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param byteArray The ByteArray to output + */ + std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray) { out << byteArray.ToHex(); diff --git a/src/Nazara/Core/ByteStream.cpp b/src/Nazara/Core/ByteStream.cpp index 175212b48..1b0fc853e 100644 --- a/src/Nazara/Core/ByteStream.cpp +++ b/src/Nazara/Core/ByteStream.cpp @@ -11,24 +11,61 @@ namespace Nz { + /*! + * \class Nz::ByteStream + * \brief Core class that represents a stream of bytes + */ + + /*! + * \brief Constructs a ByteStream object with a byte array + * + * \param byteArray Bytes to stream + * \param openMode Reading/writing mode for the stream + */ + ByteStream::ByteStream(ByteArray* byteArray, UInt32 openMode) : ByteStream() { SetStream(byteArray, openMode); } + /*! + * \brief Constructs a ByteStream object with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + ByteStream::ByteStream(void* ptr, Nz::UInt64 size) : ByteStream() { SetStream(ptr, size); } + /*! + * \brief Constructs a ByteStream object with a raw memory and a size + * + * \param ptr Constant pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + ByteStream::ByteStream(const void* ptr, Nz::UInt64 size) : ByteStream() { SetStream(ptr, size); } + /*! + * \brief Sets this with a byte array + * + * \param byteArray Bytes to stream + * \param openMode Reading/writing mode for the stream + */ + void ByteStream::SetStream(ByteArray* byteArray, UInt32 openMode) { std::unique_ptr stream(new MemoryStream(byteArray, openMode)); @@ -38,6 +75,15 @@ namespace Nz m_ownedStream = std::move(stream); } + /*! + * \brief Sets this with a raw memory and a size + * + * \param ptr Pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + void ByteStream::SetStream(void* ptr, Nz::UInt64 size) { std::unique_ptr stream(new MemoryView(ptr, size)); @@ -47,6 +93,15 @@ namespace Nz m_ownedStream = std::move(stream); } + /*! + * \brief Sets this with a raw memory and a size + * + * \param ptr Constant pointer to raw memory + * \param size Size that can be read + * + * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + */ + void ByteStream::SetStream(const void* ptr, Nz::UInt64 size) { std::unique_ptr stream(new MemoryView(ptr, size)); @@ -56,6 +111,12 @@ namespace Nz m_ownedStream = std::move(stream); } + /*! + * \brief Signal function (meant to be virtual) + * + * \remark Produces a NazaraError + */ + void ByteStream::OnEmptyStream() { NazaraError("No stream"); From 07547bdd9f59a70aee0ea4e03ab0fbe82c994cff Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:34:59 +0100 Subject: [PATCH 116/229] Documentation for Logger Former-commit-id: b09dda8a542782667070ea8bf912b552dd6b478a --- src/Nazara/Core/AbstractLogger.cpp | 25 ++++++++++-- src/Nazara/Core/FileLogger.cpp | 63 +++++++++++++++++++++++++++++- src/Nazara/Core/Log.cpp | 60 +++++++++++++++++++++++++++- src/Nazara/Core/StdLogger.cpp | 21 +++++----- 4 files changed, 152 insertions(+), 17 deletions(-) diff --git a/src/Nazara/Core/AbstractLogger.cpp b/src/Nazara/Core/AbstractLogger.cpp index 1397d3592..06695a928 100644 --- a/src/Nazara/Core/AbstractLogger.cpp +++ b/src/Nazara/Core/AbstractLogger.cpp @@ -11,17 +11,34 @@ namespace Nz namespace { const char* errorType[] = { - "Assert failed: ", // ErrorType_AssertFailed - "Internal error: ", // ErrorType_Internal - "Error: ", // ErrorType_Normal - "Warning: " // ErrorType_Warning + "Assert failed: ", // ErrorType_AssertFailed + "Internal error: ", // ErrorType_Internal + "Error: ", // ErrorType_Normal + "Warning: " // ErrorType_Warning }; static_assert(sizeof(errorType) / sizeof(const char*) == ErrorType_Max + 1, "Error type array is incomplete"); } + /*! + * \class Nz::AbstractLogger + * \brief Core class that represents the behaviour of the log classes + * + * \remark This class is abstract + */ + AbstractLogger::~AbstractLogger() = default; + /*! + * \brief Writes the error in StringStream + * + * \param type Enumeration of type ErrorType + * \param error String describing the error + * \param line Line number in the file + * \param file Filename + * \param function Name of the function throwing the error + */ + void AbstractLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function) { StringStream stream; diff --git a/src/Nazara/Core/FileLogger.cpp b/src/Nazara/Core/FileLogger.cpp index d8f23a1b1..6a94787bd 100644 --- a/src/Nazara/Core/FileLogger.cpp +++ b/src/Nazara/Core/FileLogger.cpp @@ -12,6 +12,17 @@ namespace Nz { + /*! + * \class Nz::FileLogger + * \brief Core class that represents a file logger + */ + + /*! + * \brief Constructs a FileLogger object with a file name + * + * \param logPath Path to log + */ + FileLogger::FileLogger(const String& logPath) : m_outputFile(logPath), m_forceStdOutput(false), @@ -20,28 +31,64 @@ namespace Nz { } + /*! + * \brief Destructs the object + */ + FileLogger::~FileLogger() = default; + /*! + * \brief Enables the log of the time + * + * \param enable If true, enables the time log + */ + void FileLogger::EnableTimeLogging(bool enable) { m_timeLoggingEnabled = enable; } + /*! + * \brief Enables the replication to the stdout + * + * \param enable If true, enables the replication + */ + void FileLogger::EnableStdReplication(bool enable) { m_stdReplicationEnabled = enable; } + /*! + * \brief Checks whether or not the replication to the stdout is enabled + * \return true If replication is enabled + */ + bool FileLogger::IsStdReplicationEnabled() { return m_stdReplicationEnabled; } + /*! + * \brief Checks whether or not the logging of the time is enabled + * \return true If logging of the time is enabled + */ + bool FileLogger::IsTimeLoggingEnabled() { return m_timeLoggingEnabled; } + /*! + * \brief Writes a string in the log + * + * \param string String to log + * + * \remark Produces a NazaraError if file could not be opened + * + * \see WriteError + */ + void FileLogger::Write(const String& string) { if (m_forceStdOutput || m_stdReplicationEnabled) @@ -54,8 +101,8 @@ namespace Nz // To prevent infinite loops m_forceStdOutput = true; - CallOnExit resetOnExit([this] () - { + CallOnExit resetOnExit([this] () + { m_forceStdOutput = false; }); @@ -85,6 +132,18 @@ namespace Nz m_outputFile.Write(stream); } + /*! + * \brief Writes an error in the log + * + * \param type The error type + * \param error The error text + * \param line The line the error occurred + * \param file The file the error occurred + * \param function The function the error occurred + * + * \see Write + */ + void FileLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function) { if (m_forceStdOutput || m_stdReplicationEnabled) diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index e554b7631..1a658c97e 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -15,21 +15,48 @@ namespace Nz StdLogger s_stdLogger; } + /*! + * \class Nz::Log + * \brief Core class that represents a logger + */ + + /*! + * \brief Enables the log + * + * \param enable If true, enables the log + */ + void Log::Enable(bool enable) { s_enabled = enable; } + /*! + * \brief Gets the logger + * \return An abstract pointer to the logger + */ + AbstractLogger* Log::GetLogger() { return s_logger; } + /*! + * \brief Checks whether or not the logging is enabled + * \return true If logging is enabled + */ + bool Log::IsEnabled() { return s_enabled; } + /*! + * \brief Sets the logger + * + * \param logger AbstractLogger to log + */ + void Log::SetLogger(AbstractLogger* logger) { if (s_logger != &s_stdLogger) @@ -40,28 +67,57 @@ namespace Nz s_logger = &s_stdLogger; } + /*! + * \brief Writes a string in the log + * + * \param string String to log + * + * \see WriteError + */ + void Log::Write(const String& string) { if (s_enabled) s_logger->Write(string); - + OnLogWrite(string); } + /*! + * \brief Writes the error in the log + * + * \param type Type of the error + * \param error Message of the error + * \param line Line of the error + * \param file File of the error + * \param function Function of the error + * + * \see Write + */ + void Log::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function) { if (s_enabled) s_logger->WriteError(type, error, line, file, function); - + OnLogWriteError(type, error, line, file, function); } + /*! + * \brief Initializes the Log class + * \return true if successful + */ + bool Log::Initialize() { SetLogger(new FileLogger()); return true; } + /*! + * \brief Unitializes the Log class + */ + void Log::Uninitialize() { SetLogger(nullptr); diff --git a/src/Nazara/Core/StdLogger.cpp b/src/Nazara/Core/StdLogger.cpp index 49752db26..783957ef1 100644 --- a/src/Nazara/Core/StdLogger.cpp +++ b/src/Nazara/Core/StdLogger.cpp @@ -13,8 +13,8 @@ namespace Nz const char* errorType[] = { "Assert failed", // ErrorType_AssertFailed "Internal error", // ErrorType_Internal - "Error", // ErrorType_Normal - "Warning" // ErrorType_Warning + "Error", // ErrorType_Normal + "Warning" // ErrorType_Warning }; static_assert(sizeof(errorType) / sizeof(const char*) == ErrorType_Max + 1, "Error type array is incomplete"); @@ -22,15 +22,17 @@ namespace Nz /*! * \class Nz::StdLogger - * \brief Logger writing to standard output (stdout, stderr) + * \brief Core class that represents a logger writing to standard output (stdout, stderr) */ StdLogger::~StdLogger() = default; /*! - * \brief Enable replication to standard output + * \brief Enables replication to standard output * * Does nothing, as the std logger always write to standard output + * + * \param enable Unused argument */ void StdLogger::EnableStdReplication(bool enable) @@ -40,9 +42,8 @@ namespace Nz } /*! - * \brief Get the standard output replication status - * - * Always returns true + * \brief Gets the standard output replication status + * \return Always returns true */ bool StdLogger::IsStdReplicationEnabled() @@ -51,7 +52,8 @@ namespace Nz } /*! - * Write to the console + * \brief Writes to the console + * * \param string The log to write to the console * * \see WriteError @@ -64,7 +66,8 @@ namespace Nz } /*! - * Write an error to the console + * \brief Writes an error to the console + * * \param type The error type * \param error The error text * \param line The line the error occurred From fd627c671f0e11f53237795d1799adfd7da79416 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:36:03 +0100 Subject: [PATCH 117/229] Documentation for Synchronisation primitives Former-commit-id: 39f86b2f9cd1f44a6b8e52101458f090183707e4 --- src/Nazara/Core/ConditionVariable.cpp | 52 +++++++++++++++++++++++++ src/Nazara/Core/LockGuard.cpp | 15 +++++++ src/Nazara/Core/Mutex.cpp | 32 +++++++++++++++ src/Nazara/Core/Posix/FileImpl.cpp | 12 +++--- src/Nazara/Core/Posix/SemaphoreImpl.cpp | 4 +- src/Nazara/Core/Semaphore.cpp | 37 ++++++++++++++++++ 6 files changed, 144 insertions(+), 8 deletions(-) diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index f893c7f82..c660c6464 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -18,32 +18,84 @@ namespace Nz { + /*! + * \class Nz::ConditionVariable + * \brief Core class that represents a condition variable + * + * The ConditionVariable class is a synchronization primitive that can be used to block a thread, or multiple threads at the same time, until another thread both modifies a shared variable (the condition), and notifies the ConditionVariable + */ + + /*! + * \brief Constructs a ConditionVariable object by default + */ + ConditionVariable::ConditionVariable() { m_impl = new ConditionVariableImpl; } + /*! + * \brief Destructs the object + */ + ConditionVariable::~ConditionVariable() { delete m_impl; } + /*! + * \brief Sends a signal to one thread waiting on the condition + * + * If any threads are waiting on *this, calling Signal unblocks one of the waiting threads + * + * \see SignalAll + */ + void ConditionVariable::Signal() { m_impl->Signal(); } + /*! + * \brief Sends a signal to every threads waiting on the condition + * + * Unblocks all threads currently waiting for *this + * + * \see Signal + */ + void ConditionVariable::SignalAll() { m_impl->SignalAll(); } + /*! + * \brief Makes the thread wait on the condition + * + * Wait causes the current thread to block until the condition variable is notified or a spurious wakeup occurs + * + * \param mutex Mutex for the condition + * + * \remark Produces a NazaraAssert if mutex is invalid + */ + void ConditionVariable::Wait(Mutex* mutex) { NazaraAssert(mutex != nullptr, "Mutex must be valid"); m_impl->Wait(mutex->m_impl); } + /*! + * \brief Makes the thread wait on the condition for a certain amount of time + * + * Wait causes the current thread to block until the condition variable is notified, a specific time is reached, or a spurious wakeup occurs + * + * \param mutex Mutex for the condition + * \param timeout Time before expiration of the waiting + * + * \remark Produces a NazaraAssert if mutex is invalid + */ + bool ConditionVariable::Wait(Mutex* mutex, UInt32 timeout) { NazaraAssert(mutex != nullptr, "Mutex must be valid"); diff --git a/src/Nazara/Core/LockGuard.cpp b/src/Nazara/Core/LockGuard.cpp index b59596a7c..31c1fe559 100644 --- a/src/Nazara/Core/LockGuard.cpp +++ b/src/Nazara/Core/LockGuard.cpp @@ -8,12 +8,27 @@ namespace Nz { + /*! + * \class Nz::LockGuard + * \brief Core class that represents a mutex wrapper that provides a convenient RAII-style mechanism + */ + + /*! + * \brief Constructs a LockGuard object with a mutex + * + * \param mutex Mutex to lock + */ + LockGuard::LockGuard(Mutex& mutex) : m_mutex(mutex) { m_mutex.Lock(); } + /*! + * \brief Destructs a LockGuard object and unlocks the mutex + */ + LockGuard::~LockGuard() { m_mutex.Unlock(); diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index 1245cd801..647fffc12 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -16,26 +16,58 @@ namespace Nz { + /*! + * \class Nz::Mutex + * \brief Core class that represents a binary semaphore, a mutex + * + * \remark The mutex is recursive, it means that a thread who owns the mutex can call the same function which needs the same mutex + */ + + /*! + * \brief Constructs a Mutex object by default + */ + Mutex::Mutex() { m_impl = new MutexImpl; } + /*! + * \brief Destructs the object + */ + Mutex::~Mutex() { delete m_impl; } + /*! + * \brief Locks the mutex + * + * If another thread has already locked the mutex, a call to lock will block execution until the lock is acquired. A thread may call lock on a recursive mutex repeatedly. Ownership will only be released after the thread makes a matching number of calls to unlock + */ + void Mutex::Lock() { m_impl->Lock(); } + /*! + * \brief Tries to lock the mutex + * \return true if the lock was acquired successfully + */ + bool Mutex::TryLock() { return m_impl->TryLock(); } + /*! + * \brief Unlocks the mutex + * + * Unlocks the mutex if its level of ownership is 1 (there was exactly one more call to Lock() than there were calls to Unlock() made by this thread), reduces the level of ownership by 1 otherwise + */ + void Mutex::Unlock() { m_impl->Unlock(); diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index ddd8d4253..3fa93f6f2 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -18,8 +18,8 @@ namespace Nz void FileImpl::Close() { - if (m_fileDescriptor != -1) - close(m_fileDescriptor); + if (m_fileDescriptor != -1) + close(m_fileDescriptor); } bool FileImpl::EndOfFile() const @@ -62,16 +62,16 @@ namespace Nz flags = O_CREAT | O_WRONLY; else return false; - + if (mode & OpenMode_Append) flags |= O_APPEND; if (mode & OpenMode_Truncate) flags |= O_TRUNC; - ///TODO: lock - // if ((mode & OpenMode_Lock) == 0) - // shareMode |= FILE_SHARE_WRITE; + ///TODO: lock + //if ((mode & OpenMode_Lock) == 0) + // shareMode |= FILE_SHARE_WRITE; m_fileDescriptor = open64(filePath.GetConstBuffer(), flags, permissions); return m_fileDescriptor != -1; diff --git a/src/Nazara/Core/Posix/SemaphoreImpl.cpp b/src/Nazara/Core/Posix/SemaphoreImpl.cpp index 4342cf1c6..eb1b7d1dd 100644 --- a/src/Nazara/Core/Posix/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Posix/SemaphoreImpl.cpp @@ -13,7 +13,7 @@ namespace Nz { SemaphoreImpl::SemaphoreImpl(unsigned int count) { - if(sem_init(&m_semaphore, 0, count) != 0) + if (sem_init(&m_semaphore, 0, count) != 0) NazaraError("Failed to create semaphore: " + Error::GetLastSystemError()); } @@ -68,7 +68,7 @@ namespace Nz return true; #else - return sem_timedwait(&m_semaphore, &ti) != 0; + return sem_timedwait(&m_semaphore, &ti) != 0; #endif } } diff --git a/src/Nazara/Core/Semaphore.cpp b/src/Nazara/Core/Semaphore.cpp index 1a9afdc95..c5d9cc5b7 100644 --- a/src/Nazara/Core/Semaphore.cpp +++ b/src/Nazara/Core/Semaphore.cpp @@ -16,31 +16,68 @@ namespace Nz { + /*! + * \class Nz::Semaphore + * \brief Core class that represents a counting semaphore + */ + + /*! + * \brief Constructs a semaphore object with a count + */ + Semaphore::Semaphore(unsigned int count) { m_impl = new SemaphoreImpl(count); } + /*! + * \brief Destructs the object + */ + Semaphore::~Semaphore() { delete m_impl; } + /*! + * \brief Gets the number of count that can handle the semaphore + * \return Number of count associated with the semaphore + */ + unsigned int Semaphore::GetCount() const { return m_impl->GetCount(); } + /*! + * \brief Increments the count of the semaphore and wait if count equals zero + * + * Increments the value of semaphore variable by 1. After the increment, if the pre-increment value was negative (meaning there are processes waiting for a resource), it transfers a blocked process from the semaphore's waiting queue to the ready queue + */ + void Semaphore::Post() { m_impl->Post(); } + /*! + * \brief Decrements the count of the semaphore and wait if count equals zero + * + * If the value of semaphore variable is not negative, decrements it by 1. If the semaphore variable is now negative, the process executing Wait is blocked (i.e., added to the semaphore's queue) until the value is greater or equal to 1. Otherwise, the process continues execution, having used a unit of the resource + */ + void Semaphore::Wait() { m_impl->Wait(); } + /*! + * \brief Decrements the count of the semaphore and wait if count equals zero + * \return true if the semaphore successfully decrements before timeout + * + * If the value of semaphore variable is not negative, decrements it by 1. If the semaphore variable is now negative, the process executing Wait is blocked (i.e., added to the semaphore's queue) until the value is greater or equal to 1. Otherwise, the process continues execution, having used a unit of the resource + */ + bool Semaphore::Wait(UInt32 timeout) { return m_impl->Wait(timeout); From a82c33c314287b5e888939eddbb55ee395d7e83d Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:36:49 +0100 Subject: [PATCH 118/229] Documentation for Stream Former-commit-id: 0e77be8d238879c114c5e7b166ae646254fac9eb --- include/Nazara/Core/Stream.inl | 71 ++++++++++++++++++++++++++++++++++ src/Nazara/Core/Stream.cpp | 46 +++++++++++++++++++++- 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index 104d5e300..fa90682b0 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -7,12 +7,25 @@ namespace Nz { + /*! + * \brief Constructs a Stream object with options + * + * \param streamOptions Options for the stream + * \param openMode Reading/writing mode for the stream + */ + inline Stream::Stream(UInt32 streamOptions, UInt32 openMode) : m_openMode(openMode), m_streamOptions(streamOptions) { } + /*! + * \brief Enables the text mode + * + * \param textMode Enables the mode or disables + */ + inline void Stream::EnableTextMode(bool textMode) { if (textMode) @@ -21,6 +34,12 @@ namespace Nz m_streamOptions &= ~StreamOption_Text; } + /*! + * \brief Flushes the stream + * + * \remark Produces a NazaraAssert if file is not writable + */ + inline void Stream::Flush() { NazaraAssert(IsWritable(), "Stream is not writable"); @@ -28,36 +47,77 @@ namespace Nz FlushStream(); } + /*! + * \brief Gets the open mode of the stream + * \return Reading/writing mode for the stream + */ + inline UInt32 Stream::GetOpenMode() const { return m_openMode; } + /*! + * \brief Gets the options of the stream + * \return Options of the stream + */ + inline UInt32 Stream::GetStreamOptions() const { return m_streamOptions; } + /*! + * \brief Checks whether the stream is readable + * \return true if it is the case + */ + inline bool Stream::IsReadable() const { return (m_openMode & OpenMode_ReadOnly) != 0; } + /*! + * \brief Checks whether the stream is sequential + * \return true if it is the case + */ + inline bool Stream::IsSequential() const { return (m_streamOptions & StreamOption_Sequential) != 0; } + /*! + * \brief Checks whether the stream has text mode enabled + * \return true if it is the case + */ + inline bool Stream::IsTextModeEnabled() const { return (m_streamOptions & StreamOption_Text) != 0; } + /*! + * \brief Checks whether the stream can be written + * \return true if it is the case + */ + inline bool Stream::IsWritable() const { return (m_openMode & OpenMode_WriteOnly) != 0; } + /*! + * \brief Reads the stream and puts the result in a buffer + * \return Size of the read + * + * \param buffer Buffer to stock data + * \param size Size meant to be read + * + * \remark Produces a NazaraAssert if stream is not readable + * \remark If preallocated space of buffer is less than the size, the behaviour is undefined + */ + inline std::size_t Stream::Read(void* buffer, std::size_t size) { NazaraAssert(IsReadable(), "Stream is not readable"); @@ -65,6 +125,17 @@ namespace Nz return ReadBlock(buffer, size); } + /*! + * \brief Writes in the stream the content of a buffer + * \return Size of the writing + * + * \param buffer Buffer to get data from + * \param size Size meant to be written + * + * \remark Produces a NazaraAssert if stream is not writable + * \remark If preallocated space of buffer is less than the size, the behaviour is undefined + */ + inline std::size_t Stream::Write(const void* buffer, std::size_t size) { NazaraAssert(IsWritable(), "Stream is not writable"); diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index f8aab413e..3ddcb9fc7 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -11,22 +11,50 @@ namespace Nz { + /*! + * \class Nz::Stream + * \brief Core class that represents a stream + */ + + /*! + * \brief Destructs the object + */ + Stream::~Stream() = default; + /*! + * \brief Gets the directory of the stream + * \return Empty string (meant to be virtual) + */ + String Stream::GetDirectory() const { return String(); } + /*! + * \brief Gets the path of the stream + * \return Empty string (meant to be virtual) + */ + String Stream::GetPath() const { return String(); } + /*! + * \brief Reads characters in the stream + * \return Line containing characters + * + * \param lineSize Number of characters to read, if lineSize is 0, read as much as possible + * + * \remark Produces a NazaraWarning if cursor position could not be reset + */ + String Stream::ReadLine(unsigned int lineSize) { String line; - if (lineSize == 0) // Taille maximale indéterminée + if (lineSize == 0) // Maximal size undefined { const unsigned int bufferSize = 64; @@ -63,7 +91,7 @@ namespace Nz line.Set(lineSize, '\0'); std::size_t readSize = Read(&line[0], lineSize); std::size_t pos = line.Find('\n'); - if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier) + if (pos <= readSize) // False only if the character is not available (npos being the biggest integer) { if (m_streamOptions & StreamOption_Text && pos > 0 && line[pos - 1] == '\r') line.Resize(pos); @@ -80,12 +108,26 @@ namespace Nz return line; } + /*! + * \brief Writes a ByteArray into the stream + * \return true if successful + * + * \param byteArray Bytes to write + */ + bool Stream::Write(const ByteArray& byteArray) { ByteArray::size_type size = byteArray.GetSize(); return Write(byteArray.GetConstBuffer(), size) == size; } + /*! + * \brief Writes a String into the stream + * \return true if successful + * + * \param string String to write + */ + bool Stream::Write(const String& string) { String temp(string); From 5a5f25a950e8f6349d3f48a4f3526d4c93cd7194 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:37:37 +0100 Subject: [PATCH 119/229] Documentation for Documentation & File Former-commit-id: 8a69e6dca76fba4a23b36c563b52c4ccbbec7309 --- include/Nazara/Core/File.inl | 16 ++ src/Nazara/Core/Directory.cpp | 173 +++++++++++++++- src/Nazara/Core/File.cpp | 374 +++++++++++++++++++++++++++++++--- 3 files changed, 523 insertions(+), 40 deletions(-) diff --git a/include/Nazara/Core/File.inl b/include/Nazara/Core/File.inl index 818d0098f..ff0d148fd 100644 --- a/include/Nazara/Core/File.inl +++ b/include/Nazara/Core/File.inl @@ -8,11 +8,27 @@ namespace Nz { + /*! + * \brief Computes the hash for the file + * \return ByteArray represing the result of the hash of the file + * + * \param hash Hash to execute + * \param filePath Path for the file + */ + inline ByteArray File::ComputeHash(HashType hash, const String& filePath) { return ComputeHash(AbstractHash::Get(hash).get(), filePath); } + /*! + * \brief Computes the hash for the file + * \return ByteArray represing the result of the hash of the file + * + * \param hash Hash to execute + * \param filePath Path for the file + */ + inline ByteArray File::ComputeHash(AbstractHash* hash, const String& filePath) { return Nz::ComputeHash(hash, File(filePath)); diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index ed8ed6bd0..b076b38d7 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -30,16 +30,31 @@ namespace Nz { namespace { - //FIXME: MinGW seems to dislike thread_local shared_ptr.. (using a std::string is a working hackfix) + //FIXME: MinGW seems to dislike thread_local shared_ptr.. (using a std::string is a working hackfix) thread_local std::string currentPath(DirectoryImpl::GetCurrent()); } + /*! + * \class Nz::Directory + * \brief Core class that represents a directory + */ + + /*! + * \brief Constructs a Directory object by default + */ + Directory::Directory() : m_pattern('*'), m_impl(nullptr) { } + /*! + * \brief Constructs a Directory object with a path + * + * \param dirPath Path to the directory + */ + Directory::Directory(const String& dirPath) : m_dirPath(dirPath), m_pattern('*'), @@ -47,11 +62,21 @@ namespace Nz { } + /*! + * \brief Destructs the object and calls Close + * + * \see Close + */ + Directory::~Directory() { Close(); } + /*! + * \brief Closes the directory + */ + void Directory::Close() { NazaraLock(m_mutex); @@ -64,16 +89,26 @@ namespace Nz } } + /*! + * \brief Checks whether the directory exists + * \return true if directory exists + */ + bool Directory::Exists() const { NazaraLock(m_mutex); if (IsOpen()) - return true; // Le fichier est ouvert, donc il existe + return true; // If directory is open, then it exists else return Exists(m_dirPath); } + /*! + * \brief Gets the path of the directory + * \return Path of the directory + */ + String Directory::GetPath() const { NazaraLock(m_mutex); @@ -81,6 +116,11 @@ namespace Nz return m_dirPath; } + /*! + * \brief Gets the pattern for the path of the directory + * \return Pattern for the path of the directory + */ + String Directory::GetPattern() const { NazaraLock(m_mutex); @@ -88,12 +128,19 @@ namespace Nz return m_pattern; } + /*! + * \brief Gets the result name of the directory + * \return Resulting name + * + * \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined + */ + String Directory::GetResultName() const { NazaraLock(m_mutex); #if NAZARA_CORE_SAFE - if (!m_impl) + if (!IsOpen()) { NazaraError("Directory not opened"); return String(); @@ -103,12 +150,19 @@ namespace Nz return m_impl->GetResultName(); } + /*! + * \brief Gets the result path of the directory + * \return Resulting path + * + * \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined + */ + String Directory::GetResultPath() const { NazaraLock(m_mutex); #if NAZARA_CORE_SAFE - if (!m_impl) + if (!IsOpen()) { NazaraError("Directory not opened"); return String(); @@ -118,12 +172,19 @@ namespace Nz return m_dirPath + NAZARA_DIRECTORY_SEPARATOR + m_impl->GetResultName(); } + /*! + * \brief Gets the resulting size of the directory + * \return Size of the directory + * + * \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined + */ + UInt64 Directory::GetResultSize() const { NazaraLock(m_mutex); #if NAZARA_CORE_SAFE - if (!m_impl) + if (!IsOpen()) { NazaraError("Directory not opened"); return 0; @@ -133,6 +194,11 @@ namespace Nz return m_impl->GetResultSize(); } + /*! + * \brief Checks whether the directory is open + * \return true if open + */ + bool Directory::IsOpen() const { NazaraLock(m_mutex); @@ -140,12 +206,19 @@ namespace Nz return m_impl != nullptr; } + /*! + * \brief Checks whether the directory is result + * \return true if result + * + * \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined + */ + bool Directory::IsResultDirectory() const { NazaraLock(m_mutex); #if NAZARA_CORE_SAFE - if (!m_impl) + if (!IsOpen()) { NazaraError("Directory not opened"); return false; @@ -155,12 +228,21 @@ namespace Nz return m_impl->IsResultDirectory(); } + /*! + * \brief Sets the next result in the directory + * \return true if directory has a next result + * + * \param skipDots Skips the dots in the path + * + * \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined + */ + bool Directory::NextResult(bool skipDots) { NazaraLock(m_mutex); #if NAZARA_CORE_SAFE - if (!m_impl) + if (!IsOpen()) { NazaraError("Directory not opened"); return false; @@ -185,6 +267,11 @@ namespace Nz return true; } + /*! + * \brief Opens the directory + * \return true if opening is successful + */ + bool Directory::Open() { NazaraLock(m_mutex); @@ -206,6 +293,12 @@ namespace Nz return true; } + /*! + * \brief Sets the path of the directory + * + * \param dirPath Path of the directory + */ + void Directory::SetPath(const String& dirPath) { NazaraLock(m_mutex); @@ -215,6 +308,12 @@ namespace Nz m_dirPath = File::AbsolutePath(dirPath); } + /*! + * \brief Sets the pattern of the directory + * + * \param dirPath Pattern of the directory + */ + void Directory::SetPattern(const String& pattern) { NazaraLock(m_mutex); @@ -222,6 +321,18 @@ namespace Nz m_pattern = pattern; } + /*! + * \brief Copies the first directory to a new directory path + * \return true if copy is successful + * + * \param sourcePath Path of the original directory + * \param targetPath Path of the copied directory + * + * \remark Produces a NazaraError if could not create destination directory + * \remark Produces a NazaraError if could not open origin directory + * \remark Produces a NazaraError if could not copy a file + */ + bool Directory::Copy(const String& sourcePath, const String& destPath) { if (sourcePath.IsEmpty() || destPath.IsEmpty()) @@ -262,6 +373,14 @@ namespace Nz return true; } + /*! + * \brief Creates a directory from a path + * \return true if creation is successful + * + * \param dirPath Path of the directory + * \param recursive Creates subdirectories + */ + bool Directory::Create(const String& dirPath, bool recursive) { if (dirPath.IsEmpty()) @@ -275,7 +394,7 @@ namespace Nz return false; #ifdef NAZARA_PLATFORM_WINDOWS - // Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop") + // Unlike to disk (Ex: "C:"), the netwrok path is not considered as a directory (Ex: "\\Laptop") if (path.Match("\\\\*")) { foundPos = path.Find('\\', 2); @@ -309,6 +428,13 @@ namespace Nz return DirectoryImpl::Create(File::NormalizePath(dirPath)); } + /*! + * \brief Checks whether the directory exists + * \return true if directory exists + * + * \param dirPath Path of the directory + */ + bool Directory::Exists(const String& dirPath) { if (dirPath.IsEmpty()) @@ -317,14 +443,24 @@ namespace Nz return DirectoryImpl::Exists(File::NormalizePath(dirPath)); } + /*! + * \brief Gets the current path of this directory + * \return Current path + */ + String Directory::GetCurrent() { return currentPath; } + /*! + * \brief Gets this current file relative to the engine + * \return Path to this file + */ + const char* Directory::GetCurrentFileRelativeToEngine(const char* currentFile) { - ///FIXME: Est-ce que cette méthode est au bon endroit ? + ///FIXME: Is this method in the right place ? const char* ptr = std::strstr(currentFile, "NazaraEngine/"); if (!ptr) ptr = std::strstr(currentFile, "NazaraEngine\\"); @@ -335,6 +471,14 @@ namespace Nz return ptr; } + /*! + * \brief Removes the directory + * \return true if remove is successful + * + * \param dirPath Path of the directory + * \param emptyDirectory Remove recursively + */ + bool Directory::Remove(const String& dirPath, bool emptyDirectory) { if (dirPath.IsEmpty()) @@ -344,7 +488,7 @@ namespace Nz { Directory dir(dirPath); if (!dir.Open()) - return DirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer + return DirectoryImpl::Remove(dirPath); // If we can't open the directory, we try to delete it while (dir.NextResult(true)) { @@ -366,6 +510,13 @@ namespace Nz return DirectoryImpl::Remove(File::NormalizePath(dirPath)); } + /*! + * \brief Sets the current directory + * \return true if directory path exists + * + * \param dirPath Path of the directory + */ + bool Directory::SetCurrent(const String& dirPath) { String path = File::AbsolutePath(dirPath); @@ -376,5 +527,5 @@ namespace Nz } else return false; - } + } } diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index db71f2d95..55587c9e0 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -30,23 +30,51 @@ namespace Nz { + /*! + * \class Nz::File + * \brief Core class that represents a file + */ + + /*! + * \brief Constructs a File object by default + */ + File::File() : m_impl(nullptr) { } + /*! + * \brief Constructs a File object with a file path + * + * \param filePath Path to the file + */ + File::File(const String& filePath) : File() { SetFile(filePath); } + /*! + * \brief Constructs a File object with a file path and flags + * + * \param filePath Path to the file + * \param openMode Flag of the file + */ + File::File(const String& filePath, UInt32 openMode) : File() { Open(filePath, openMode); } + /*! + * \brief Constructs a File object by move semantic + * + * \param file File to move into this + */ + File::File(File&& file) noexcept : Stream(std::move(file)), m_filePath(std::move(file.m_filePath)), @@ -55,16 +83,33 @@ namespace Nz file.m_impl = nullptr; } + /*! + * \brief Destructs the object and calls Close + * + * \see Close + */ + File::~File() { Close(); } + /*! + * \brief Copies this file to a new file path + * \return true if copy is successful + * + * \param newFilePath Path of the new file + */ + bool File::Copy(const String& newFilePath) { return Copy(m_filePath, newFilePath); } + /*! + * \brief Closes the file + */ + void File::Close() { NazaraLock(m_mutex) @@ -79,6 +124,11 @@ namespace Nz } } + /*! + * \brief Deletes the file + * \return true if delete is successful + */ + bool File::Delete() { NazaraLock(m_mutex) @@ -88,6 +138,13 @@ namespace Nz return Delete(m_filePath); } + /*! + * \brief Checks whether the file has reached the end + * \return true if cursor is at the end of the file + * + * \remark Produces a NazaraError if file is not open with NAZARA_CORE_SAFE defined + */ + bool File::EndOfFile() const { NazaraLock(m_mutex) @@ -95,7 +152,7 @@ namespace Nz #if NAZARA_CORE_SAFE if (!IsOpen()) { - NazaraError("File not opened"); + NazaraError("File not open"); return false; } #endif @@ -103,11 +160,25 @@ namespace Nz return m_impl->EndOfFile(); } + /*! + * \brief Checks whether the file has reached the end of the stream + * \return true if cursor is at the end of the file + * + * \remark Produces a NazaraError if file is not open with NAZARA_CORE_SAFE defined + * + * \see EndOfFile + */ + bool File::EndOfStream() const { return EndOfFile(); } + /*! + * \brief Checks whether the file exists + * \return true if file exists + */ + bool File::Exists() const { NazaraLock(m_mutex) @@ -118,6 +189,11 @@ namespace Nz return Exists(m_filePath); } + /*! + * \brief Gets the creation time of the file + * \return Information about the creation time + */ + time_t File::GetCreationTime() const { NazaraLock(m_mutex) @@ -125,15 +201,27 @@ namespace Nz return GetCreationTime(m_filePath); } + /*! + * \brief Gets the position of the cursor in the file + * \return Position of the cursor + * + * \remark Produces a NazaraAssert if file is not open + */ + UInt64 File::GetCursorPos() const { NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsOpen(), "File is not open"); return m_impl->GetCursorPos(); } + /*! + * \brief Gets the directory of the file + * \return Directory of the file + */ + String File::GetDirectory() const { NazaraLock(m_mutex) @@ -141,6 +229,11 @@ namespace Nz return m_filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true); } + /*! + * \brief Gets the name of the file + * \return Name of the file + */ + String File::GetFileName() const { NazaraLock(m_mutex) @@ -148,6 +241,11 @@ namespace Nz return m_filePath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); } + /*! + * \brief Gets the last time the file was accessed + * \return Information about the last access time + */ + time_t File::GetLastAccessTime() const { NazaraLock(m_mutex) @@ -155,6 +253,11 @@ namespace Nz return GetLastAccessTime(m_filePath); } + /*! + * \brief Gets the last time the file was written + * \return Information about the last writing time + */ + time_t File::GetLastWriteTime() const { NazaraLock(m_mutex) @@ -162,6 +265,11 @@ namespace Nz return GetLastWriteTime(m_filePath); } + /*! + * \brief Gets the path of the file + * \return Path of the file + */ + String File::GetPath() const { NazaraLock(m_mutex) @@ -169,6 +277,11 @@ namespace Nz return m_filePath; } + /*! + * \brief Gets the size of the file + * \return Size of the file + */ + UInt64 File::GetSize() const { NazaraLock(m_mutex) @@ -176,6 +289,11 @@ namespace Nz return GetSize(m_filePath); } + /*! + * \brief Checks whether the file is open + * \return true if open + */ + bool File::IsOpen() const { NazaraLock(m_mutex) @@ -183,22 +301,14 @@ namespace Nz return m_impl != nullptr; } - bool File::Rename(const String& newFilePath) - { - NazaraLock(m_mutex) - - bool opened = IsOpen(); - Close(); - - bool success = Rename(m_filePath, newFilePath); - if (success) - m_filePath = NormalizePath(newFilePath); - - if (opened) - Open(); - - return success; - } + /*! + * \brief Opens the file with flags + * \return true if opening is successful + * + * \param openMode Flag for file + * + * \remark Produces a NazaraError if OS error to open a file + */ bool File::Open(unsigned int openMode) { @@ -215,7 +325,7 @@ namespace Nz std::unique_ptr impl(new FileImpl(this)); if (!impl->Open(m_filePath, openMode)) { - ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut + ErrorFlags flags(ErrorFlag_Silent); // Silent by default NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError()); return false; } @@ -231,6 +341,16 @@ namespace Nz return true; } + /*! + * \brief Opens the file with file path and flags + * \return true if opening is successful + * + * \param filePath Path to the file + * \param openMode Flag for file + * + * \remark Produces a NazaraError if OS error to open a file + */ + bool File::Open(const String& filePath, unsigned int openMode) { NazaraLock(m_mutex) @@ -241,24 +361,72 @@ namespace Nz return Open(openMode); } + /*! + * \brief Renames the file with a new name + * \return true if rename is successful + */ + + bool File::Rename(const String& newFilePath) + { + NazaraLock(m_mutex) + + bool open = IsOpen(); + Close(); + + bool success = Rename(m_filePath, newFilePath); + if (success) + m_filePath = NormalizePath(newFilePath); + + if (open) + Open(); + + return success; + } + + /*! + * \brief Sets the position of the cursor + * \return true if cursor is successfully positioned + * + * \param pos Position of the cursor + * \param offset Offset according to the cursor position + * + * \remark Produces a NazaraAssert if file is not open + */ + bool File::SetCursorPos(CursorPosition pos, Int64 offset) { NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsOpen(), "File is not open"); return m_impl->SetCursorPos(pos, offset); } + /*! + * \brief Sets the position of the cursor + * \return true if cursor is successfully positioned + * + * \param offset Offset according to the cursor begin position + * + * \remark Produces a NazaraAssert if file is not open + */ + bool File::SetCursorPos(UInt64 offset) { NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsOpen(), "File is not open"); return m_impl->SetCursorPos(CursorPosition_AtBegin, offset); } + /*! + * \brief Sets the file path + * \return true if file opening is successful + * + * \remark Produces a NazaraError if file path can not be open + */ + bool File::SetFile(const String& filePath) { NazaraLock(m_mutex) @@ -285,6 +453,13 @@ namespace Nz return true; } + /*! + * \brief Sets the file path + * \return A reference to this + * + * \remark Produces a NazaraError if file path can not be open + */ + File& File::operator=(const String& filePath) { SetFile(filePath); @@ -292,6 +467,13 @@ namespace Nz return *this; } + /*! + * \brief Moves the other file into this + * \return A reference to this + * + * \param file File to move in this + */ + File& File::operator=(File&& file) noexcept { NazaraLock(m_mutex) @@ -302,9 +484,18 @@ namespace Nz return *this; } + /*! + * \brief Gets the absolute path of the file + * \return Absolute path of the file + * + * \param filePath Path of the file + * + * \remark Produces a NazaraError if filePath is weird with NAZARA_PLATFORM_WINDOWS defined + */ + String File::AbsolutePath(const String& filePath) { - // Je n'utilise pas les fonctions de l'OS car elles ne fonctionnent que pour un chemin existant + // We don't use OS functions because they only work for existing path String path = NormalizePath(filePath); if (path.IsEmpty()) return String(); @@ -319,7 +510,7 @@ namespace Nz base = "\\\\"; start = 2; } - else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine + else if (path.StartsWith('\\')) // Special : '\' refering to root { String drive = Directory::GetCurrent().SubStringTo('\\'); String end = path.SubString(1, -1); @@ -351,14 +542,14 @@ namespace Nz if (path.Split(sep, NAZARA_DIRECTORY_SEPARATOR) <= 1) return path; - // Nous avons un chemin absolu, mais il nous faut un peu le nettoyer + // We have the absolute path, but we need to clean it up for (unsigned int i = 0; i < sep.size(); ++i) { if (sep[i] == '.') sep.erase(sep.begin() + i--); else if (sep[i] == "..") { - if (i > start) // Si nous ne sommes pas dans la partie protégée + if (i > start) // If we are not in the protected area sep.erase(sep.begin() + i--); sep.erase(sep.begin() + i--); @@ -377,6 +568,14 @@ namespace Nz return stream; } + /*! + * \brief Copies the first file to a new file path + * \return true if copy is successful + * + * \param sourcePath Path of the original file + * \param targetPath Path of the copied file + */ + bool File::Copy(const String& sourcePath, const String& targetPath) { if (sourcePath.IsEmpty() || targetPath.IsEmpty()) @@ -385,6 +584,13 @@ namespace Nz return FileImpl::Copy(NormalizePath(sourcePath), NormalizePath(targetPath)); } + /*! + * \brief Deletes the file + * \return true if delete is successful + * + * \param filePath Path of the file + */ + bool File::Delete(const String& filePath) { if (filePath.IsEmpty()) @@ -393,6 +599,13 @@ namespace Nz return FileImpl::Delete(NormalizePath(filePath)); } + /*! + * \brief Checks whether the file exists + * \return true if file exists + * + * \param filePath Path of the file + */ + bool File::Exists(const String& filePath) { if (filePath.IsEmpty()) @@ -401,6 +614,13 @@ namespace Nz return FileImpl::Exists(NormalizePath(filePath)); } + /*! + * \brief Gets the creation time of the file + * \return Information about the creation time + * + * \param filePath Path of the file + */ + time_t File::GetCreationTime(const String& filePath) { if (filePath.IsEmpty()) @@ -409,10 +629,23 @@ namespace Nz return FileImpl::GetCreationTime(NormalizePath(filePath)); } + /*! + * \brief Gets the directory of the file + * \return Directory of the file + * + * \param filePath Path of the file + */ + String File::GetDirectory(const String& filePath) { return filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true); } + /*! + * \brief Gets the last time the file was accessed + * \return Information about the last access time + * + * \param filePath Path of the file + */ time_t File::GetLastAccessTime(const String& filePath) { @@ -422,6 +655,13 @@ namespace Nz return FileImpl::GetLastAccessTime(NormalizePath(filePath)); } + /*! + * \brief Gets the last time the file was written + * \return Information about the last writing time + * + * \param filePath Path of the file + */ + time_t File::GetLastWriteTime(const String& filePath) { if (filePath.IsEmpty()) @@ -430,6 +670,13 @@ namespace Nz return FileImpl::GetLastWriteTime(NormalizePath(filePath)); } + /*! + * \brief Gets the size of the file + * \return Size of the file + * + * \param filePath Path of the file + */ + UInt64 File::GetSize(const String& filePath) { if (filePath.IsEmpty()) @@ -438,6 +685,13 @@ namespace Nz return FileImpl::GetSize(NormalizePath(filePath)); } + /*! + * \brief Checks whether the file path is absolute + * \return true if path is absolute + * + * \param filePath Path to test + */ + bool File::IsAbsolute(const String& filePath) { String path(filePath.Trimmed()); @@ -451,7 +705,7 @@ namespace Nz return true; else if (path.Match("\\\\*")) // Ex: \\Laptop return true; - else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine + else if (path.StartsWith('\\')) // Special : '\' refering to the root return true; else return false; @@ -462,6 +716,13 @@ namespace Nz #endif } + /*! + * \brief Normalizes the file path + * \return Path normalized (replacing '/' with '\\' on Windows, ...) + * + * \param filePath Path to normalize + */ + String File::NormalizePath(const String& filePath) { String path = NormalizeSeparators(filePath.Trimmed()); @@ -475,6 +736,13 @@ namespace Nz return path; } + /*! + * \brief Normalizes the path separator + * \return Path normalized (replacing '/' with '\\' on Windows, ...) + * + * \param filePath Path to normalize + */ + String File::NormalizeSeparators(const String& filePath) { String path(filePath); @@ -490,6 +758,14 @@ namespace Nz return path; } + /*! + * \brief Renames the file with a new name + * \return true if rename is successful + * + * \param sourcePath Path of the original file + * \param targetPath Path of the renamed file + */ + bool File::Rename(const String& sourcePath, const String& targetPath) { if (sourcePath.IsEmpty() || targetPath.IsEmpty()) @@ -498,6 +774,12 @@ namespace Nz return FileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath)); } + /*! + * \brief Flushes the stream + * + * \remark Produces a NazaraAssert if file is not open + */ + void File::FlushStream() { NazaraLock(m_mutex) @@ -507,11 +789,21 @@ namespace Nz m_impl->Flush(); } + /*! + * \brief Reads blocks + * \return Number of blocks read + * + * \param buffer Preallocated buffer to contain information read + * \param size Size of the read and thus of the buffer + * + * \remark Produces a NazaraAssert if file is not open + */ + std::size_t File::ReadBlock(void* buffer, std::size_t size) { NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsOpen(), "File is not open"); if (size == 0) return 0; @@ -520,7 +812,7 @@ namespace Nz return m_impl->Read(buffer, size); else { - // Si nous ne devons rien lire, nous avançons simplement + // If we don't have to read, we move forward UInt64 currentPos = m_impl->GetCursorPos(); m_impl->SetCursorPos(CursorPosition_AtCurrent, size); @@ -529,11 +821,22 @@ namespace Nz } } + /*! + * \brief Writes blocks + * \return Number of blocks written + * + * \param buffer Preallocated buffer containing information to write + * \param size Size of the writting and thus of the buffer + * + * \remark Produces a NazaraAssert if file is not open + * \remark Produces a NazaraAssert if buffer is nullptr + */ + std::size_t File::WriteBlock(const void* buffer, std::size_t size) { NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsOpen(), "File is not open"); if (size == 0) return 0; @@ -543,9 +846,22 @@ namespace Nz return m_impl->Write(buffer, size); } + /*! + * \brief Appends the file to the hash + * \return true if hash is successful + * + * \param hash Hash to append data of the file + * \param originalFile Path of the file + * + * \remark Produces a NazaraAssert if hash is nullptr + * \remark Produces a NazaraError if file could not be open + * \remark Produces a NazaraError if file could not be read + */ NAZARA_CORE_API bool HashAppend(AbstractHash* hash, const File& originalFile) { + NazaraAssert(hash, "Invalid hash"); + File file(originalFile.GetPath()); if (!file.Open(OpenMode_ReadOnly)) { From 99370683b3ba7014f016938f588ff25499068ead Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:38:35 +0100 Subject: [PATCH 120/229] Documentation for DynLib & PluginManager Former-commit-id: 3602bd9a6f24ed4adb38879097ea5679b55e3b99 --- include/Nazara/Core/DynLib.hpp | 4 +- include/Nazara/Core/PluginManager.hpp | 2 +- src/Nazara/Core/DynLib.cpp | 62 ++++++++++++++++++++++- src/Nazara/Core/PluginManager.cpp | 73 +++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index 767165fe4..4f2759e22 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -28,7 +28,7 @@ namespace Nz { - using DynLibFunc = int (*)(); // Type "générique" de pointeur sur fonction + using DynLibFunc = int (*)(); // "Generic" type of poiter to function class DynLibImpl; @@ -56,7 +56,7 @@ namespace Nz mutable String m_lastError; DynLibImpl* m_impl; -}; + }; } #endif // NAZARA_DYNLIB_HPP diff --git a/include/Nazara/Core/PluginManager.hpp b/include/Nazara/Core/PluginManager.hpp index b2b20ffde..833f0c5d2 100644 --- a/include/Nazara/Core/PluginManager.hpp +++ b/include/Nazara/Core/PluginManager.hpp @@ -13,7 +13,7 @@ #include #include -///TODO: Révision +///TODO: Revision namespace Nz { class DynLib; diff --git a/src/Nazara/Core/DynLib.cpp b/src/Nazara/Core/DynLib.cpp index 39539e7ed..3261f0959 100644 --- a/src/Nazara/Core/DynLib.cpp +++ b/src/Nazara/Core/DynLib.cpp @@ -25,11 +25,26 @@ namespace Nz { + /*! + * \class Nz::DynLib + * \brief Core class that represents a dynamic library loader + */ + + /*! + * \brief Constructs a DynLib object by default + */ + DynLib::DynLib() : m_impl(nullptr) { } + /*! + * \brief Constructs a DynLib object by move semantic + * + * \param lib DynLib to move into this + */ + DynLib::DynLib(DynLib&& lib) : m_lastError(std::move(lib.m_lastError)), m_impl(lib.m_impl) @@ -37,11 +52,22 @@ namespace Nz lib.m_impl = nullptr; } + /*! + * \brief Destructs the object and calls Unload + * + * \see Unload + */ + DynLib::~DynLib() { Unload(); } + /*! + * \brief Gets the last error + * \return Last error + */ + String DynLib::GetLastError() const { NazaraLock(m_mutex) @@ -49,12 +75,19 @@ namespace Nz return m_lastError; } + /*! + * \brief Gets the symbol for the name + * \return Function which is the symbol of the function name + * + * \remark Produces a NazaraError if library is not loaded with NAZARA_CORE_SAFE defined + */ + DynLibFunc DynLib::GetSymbol(const String& symbol) const { NazaraLock(m_mutex) #if NAZARA_CORE_SAFE - if (!m_impl) + if (!IsLoaded()) { NazaraError("Library not opened"); return nullptr; @@ -64,11 +97,25 @@ namespace Nz return m_impl->GetSymbol(symbol, &m_lastError); } + /*! + * \brief Checks whether the library is loaded + * \return true if loaded + */ + bool DynLib::IsLoaded() const { return m_impl != nullptr; } + /*! + * \brief Loads the library with that path + * \return true if loading is successful + * + * \param libraryPath Path of the library + * + * \remark Produces a NazaraError if library is could not be loaded + */ + bool DynLib::Load(const String& libraryPath) { NazaraLock(m_mutex) @@ -87,11 +134,15 @@ namespace Nz return true; } + /*! + * \brief Unloads the library + */ + void DynLib::Unload() { NazaraLock(m_mutex) - if (m_impl) + if (IsLoaded()) { m_impl->Unload(); delete m_impl; @@ -99,6 +150,13 @@ namespace Nz } } + /*! + * \brief Moves the other lib into this + * \return A reference to this + * + * \param lib DynLib to move in this + */ + DynLib& DynLib::operator=(DynLib&& lib) { Unload(); diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index ddfede54c..04fcafac7 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -24,6 +24,19 @@ namespace Nz }; } + /*! + * \class Nz::PluginManager + * \brief Core class that represents a manager for plugin + */ + + /*! + * \brief Adds a directory + * + * \param directoryPath Path to the directory + * + * \remark Produces a NazaraError if not initialized + */ + void PluginManager::AddDirectory(const String& directoryPath) { if (!Initialize()) @@ -35,6 +48,11 @@ namespace Nz s_directories.insert(File::AbsolutePath(directoryPath)); } + /*! + * \brief Initializes the plugin manager + * \return true if everything is ok + */ + bool PluginManager::Initialize() { if (s_initialized) @@ -48,11 +66,36 @@ namespace Nz return true; } + /*! + * \brief Mounts the plugin + * \return true if mounting was a success + * + * \remark Produces a NazaraError if not initialized + * \remark Produces a NazaraError if plugin is not found + * \remark Produces a NazaraError if fail to load plugin + * \remark Produces a NazaraError if fail to get symbol PluginLoad + * \remark Produces a NazaraError if fail to initialize the plugin with PluginLoad + */ + bool PluginManager::Mount(Plugin plugin) { return Mount(s_pluginFiles[plugin]); } + /*! + * \brief Mounts the plugin with a path + * \return true if mounting was a success + * + * \param pluginPath Path to the plugin + * \param appendExtension Adds the extension to the path or not + * + * \remark Produces a NazaraError if not initialized + * \remark Produces a NazaraError if plugin is not found + * \remark Produces a NazaraError if fail to load plugin + * \remark Produces a NazaraError if fail to get symbol PluginLoad + * \remark Produces a NazaraError if fail to initialize the plugin with PluginLoad + */ + bool PluginManager::Mount(const String& pluginPath, bool appendExtension) { if (!Initialize()) @@ -119,6 +162,14 @@ namespace Nz return true; } + /*! + * \brief Removes a directory + * + * \param directoryPath Path to the directory + * + * \remark Produces a NazaraError if not initialized + */ + void PluginManager::RemoveDirectory(const String& directoryPath) { if (!Initialize()) @@ -130,11 +181,29 @@ namespace Nz s_directories.erase(File::AbsolutePath(directoryPath)); } + /*! + * \brief Unmounts the plugin with a path + * + * \param pluginPath Path to the plugin + * + * \remark Produces a NazaraError if not initialized + * \remark Produces a NazaraError if plugin is not loaded + */ + void PluginManager::Unmount(Plugin plugin) { Unmount(s_pluginFiles[plugin]); } + /*! + * \brief Unmounts the plugin with a path + * + * \param pluginPath Path to the plugin + * + * \remark Produces a NazaraError if not initialized + * \remark Produces a NazaraError if plugin is not loaded + */ + void PluginManager::Unmount(const String& pluginPath) { if (!Initialize()) @@ -160,6 +229,10 @@ namespace Nz s_plugins.erase(it); } + /*! + * \brief Uninitializes the plugin manager + */ + void PluginManager::Uninitialize() { if (!s_initialized) From ff51b9074841c44e03bd45b684a46f704a5fb857 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:39:05 +0100 Subject: [PATCH 121/229] Documentation for Error Former-commit-id: 9158cb014b813739b09b0bea7c375dc549815aef --- src/Nazara/Core/Error.cpp | 62 +++++++++++++++++++++++++++++++++- src/Nazara/Core/ErrorFlags.cpp | 28 +++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index 805e60190..59a8b72fb 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -18,11 +18,30 @@ namespace Nz { + /*! + * \class Nz::Error + * \brief Core class that represents an error + */ + + /*! + * \brief Gets the flags of the error + * \return Flag + */ + UInt32 Error::GetFlags() { return s_flags; } + /*! + * \brief Gets the last error + * \return Last error + * + * \param file Optional argument to set last error file + * \param line Optional argument to set last error line + * \param function Optional argument to set last error function + */ + String Error::GetLastError(const char** file, unsigned int* line, const char** function) { if (file) @@ -37,6 +56,11 @@ namespace Nz return s_lastError; } + /*! + * \brief Gets the last system error code + * \return "errno" + */ + unsigned int Error::GetLastSystemErrorCode() { #if defined(NAZARA_PLATFORM_WINDOWS) @@ -49,6 +73,13 @@ namespace Nz #endif } + /*! + * \brief Gets the string representation of the last system error code + * \return Message of the error + * + * \param code Code of the error + */ + String Error::GetLastSystemError(unsigned int code) { #if defined(NAZARA_PLATFORM_WINDOWS) @@ -65,7 +96,7 @@ namespace Nz String error(String::Unicode(buffer)); LocalFree(buffer); - error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message + error.Trim(); // For an unknown reason, Windows put two-three line return after the message return error; #elif defined(NAZARA_PLATFORM_POSIX) @@ -77,11 +108,27 @@ namespace Nz #endif } + /*! + * \brief Sets the flags + * + * \param flags Flags for the error + */ + void Error::SetFlags(UInt32 flags) { s_flags = flags; } + /*! + * \brief Checks if the error should trigger + * + * \param type ErrorType of the error + * \param error Message of the error + * + * \remark Produces a std::abort on AssertFailed with NAZARA_CORE_EXIT_ON_ASSERT_FAILURE defined + * \remark Produces a std::runtime_error on AssertFailed or throwing exception + */ + void Error::Trigger(ErrorType type, const String& error) { if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0) @@ -102,6 +149,19 @@ namespace Nz throw std::runtime_error(error); } + /*! + * \brief Checks if the error should trigger + * + * \param type ErrorType of the error + * \param error Message of the error + * \param line Line of the error + * \param file File of the error + * \param function Function of the error + * + * \remark Produces a std::abort on AssertFailed with NAZARA_CORE_EXIT_ON_ASSERT_FAILURE defined + * \remark Produces a std::runtime_error on AssertFailed or throwing exception + */ + void Error::Trigger(ErrorType type, const String& error, unsigned int line, const char* file, const char* function) { if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0) diff --git a/src/Nazara/Core/ErrorFlags.cpp b/src/Nazara/Core/ErrorFlags.cpp index 08c1d3e19..d29efbc5a 100644 --- a/src/Nazara/Core/ErrorFlags.cpp +++ b/src/Nazara/Core/ErrorFlags.cpp @@ -8,22 +8,50 @@ namespace Nz { + /*! + * \class Nz::ErrorFlags + * \brief Core class that represents flags for error + */ + + /*! + * \brief Constructs a ErrorFlags object with flags + * + * \param flags Flags for the error + * \param replace Replace the entirely the old flag if true, else do a "OR" + */ + ErrorFlags::ErrorFlags(UInt32 flags, bool replace) : m_previousFlags(Error::GetFlags()) { SetFlags(flags, replace); } + /*! + * \brief Destructs the object and sets the old flag + */ + ErrorFlags::~ErrorFlags() { Error::SetFlags(m_previousFlags); } + /*! + * \brief Gets the previous flag + * \return Previous flag + */ + UInt32 ErrorFlags::GetPreviousFlags() const { return m_previousFlags; } + /*! + * \brief Sets the flags + * + * \param flags Flags for the error + * \param replace Replace the entirely the old flag if true, else do a "OR" + */ + void ErrorFlags::SetFlags(UInt32 flags, bool replace) { if (!replace) From 8325db803713cc470d292844499f7de03a1f93f2 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:40:47 +0100 Subject: [PATCH 122/229] Documentation for Special files of Core Former-commit-id: 6e98fc660ee9dfaa4d8f31da337e2334b4f43442 --- include/Nazara/Core/Config.hpp | 31 +++++++++++++++-------------- include/Nazara/Core/ConfigCheck.hpp | 4 ++-- include/Nazara/Core/DebugOff.hpp | 2 +- include/Nazara/Core/Enums.hpp | 28 +++++++++++++------------- include/Nazara/Core/OffsetOf.hpp | 2 +- readme.md | 2 +- readme_fr.md | 2 +- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/include/Nazara/Core/Config.hpp b/include/Nazara/Core/Config.hpp index eee521307..bd67daec6 100644 --- a/include/Nazara/Core/Config.hpp +++ b/include/Nazara/Core/Config.hpp @@ -27,36 +27,36 @@ #ifndef NAZARA_CONFIG_CORE_HPP #define NAZARA_CONFIG_CORE_HPP -/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +/// Each modification of a parameter needs a recompilation of the module -// Précision des réels lors de la transformation en chaîne de caractère (Max. chiffres après la virgule) +// Precision of reals when transformed into string (Max. numbers after the coma) #define NAZARA_CORE_DECIMAL_DIGITS 6 -// Duplique la sortie du log sur le flux de sortie standard (cout) +// Duplicate the log output on the standard output flux (cout) #define NAZARA_CORE_DUPLICATE_LOG_TO_COUT 0 -// Teste les assertions +// Checks the assertions #define NAZARA_CORE_ENABLE_ASSERTS 0 -// Appelle exit dès qu'une assertion est invalide +// Call exit when an assertion is invalid #define NAZARA_CORE_EXIT_ON_ASSERT_FAILURE 1 -// Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash) +// Size of buffer when reading entirely a file (ex: Hash) #define NAZARA_CORE_FILE_BUFFERSIZE 4096 -// Incorpore la table Unicode Character Data (Nécessaires pour faire fonctionner le flag String::HandleUTF8) +// Incorporate the Unicode Character Data table (Necessary to make it work with the flag String::HandleUTF8) #define NAZARA_CORE_INCLUDE_UNICODEDATA 0 -// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) #define NAZARA_CORE_MANAGE_MEMORY 0 -// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +// Activate the security tests based on the code (Advised for development) #define NAZARA_CORE_SAFE 1 -// Protège les classes des accès concurrentiels +// Protect the classes against data race #define NAZARA_CORE_THREADSAFE 1 -// Les classes à protéger des accès concurrentiels +// Classes to protect against data race #define NAZARA_THREADSAFETY_CLOCK 0 // Clock #define NAZARA_THREADSAFETY_DIRECTORY 1 // Directory #define NAZARA_THREADSAFETY_DYNLIB 1 // DynLib @@ -64,18 +64,19 @@ #define NAZARA_THREADSAFETY_LOG 1 // Log #define NAZARA_THREADSAFETY_REFCOUNTED 1 // RefCounted -// Le nombre de spinlocks à utiliser avec les sections critiques de Windows (0 pour désactiver) +// Number of spinlocks to use with the Windows critical sections (0 to disable) #define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096 -// Optimise l'implémentation Windows avec certaines avancées de Windows vista (Casse la compatibilité XP) +// Optimize the Windows implementation with technologies of Windows vista (and greather) (Break the compatibility with XP) #define NAZARA_CORE_WINDOWS_VISTA 0 + /* -// Règle le temps entre le réveil du thread des timers et l'activation d'un timer (En millisecondes) +// Sets the time between waking thread timers and activating a timer (in milliseconds) #define NAZARA_CORE_TIMER_WAKEUPTIME 10 */ -/// Vérification des valeurs et types de certaines constantes +/// Checking the values and types of certain constants #include #if defined(NAZARA_STATIC) diff --git a/include/Nazara/Core/ConfigCheck.hpp b/include/Nazara/Core/ConfigCheck.hpp index 310567eef..8329f4ff0 100644 --- a/include/Nazara/Core/ConfigCheck.hpp +++ b/include/Nazara/Core/ConfigCheck.hpp @@ -7,12 +7,12 @@ #ifndef NAZARA_CONFIG_CHECK_CORE_HPP #define NAZARA_CONFIG_CHECK_CORE_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 #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// On force la valeur de MANAGE_MEMORY en mode debug +// We fore the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY #undef NAZARA_CORE_MANAGE_MEMORY #define NAZARA_CORE_MANAGE_MEMORY 0 diff --git a/include/Nazara/Core/DebugOff.hpp b/include/Nazara/Core/DebugOff.hpp index e042eff24..62788ee15 100644 --- a/include/Nazara/Core/DebugOff.hpp +++ b/include/Nazara/Core/DebugOff.hpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // 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_CORE_MANAGE_MEMORY #undef delete #undef new diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index a261f2bd3..0c0530489 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -19,9 +19,9 @@ namespace Nz enum CursorPosition { - CursorPosition_AtBegin, // Début du fichier - CursorPosition_AtCurrent, // Position du pointeur - CursorPosition_AtEnd, // Fin du fichier + CursorPosition_AtBegin, // beginning of the file + CursorPosition_AtCurrent, // Position of the cursor + CursorPosition_AtEnd, // End of the file CursorPosition_Max = CursorPosition_AtEnd }; @@ -45,7 +45,7 @@ namespace Nz ErrorFlag_ThrowException = 0x4, ErrorFlag_ThrowExceptionDisabled = 0x8, - ErrorFlag_Max = ErrorFlag_ThrowExceptionDisabled*2-1 + ErrorFlag_Max = ErrorFlag_ThrowExceptionDisabled * 2 - 1 }; enum ErrorType @@ -75,18 +75,18 @@ namespace Nz enum OpenModeFlags { - OpenMode_NotOpen = 0x00, // Utilise le mode d'ouverture actuel + OpenMode_NotOpen = 0x00, // Use the current mod of opening - OpenMode_Append = 0x01, // Empêche l'écriture sur la partie déjà existante et met le curseur à la fin - OpenMode_Lock = 0x02, // Empêche le fichier d'être modifié tant qu'il est ouvert - OpenMode_ReadOnly = 0x04, // Ouvre uniquement en lecture - OpenMode_Text = 0x10, // Ouvre en mode texte - OpenMode_Truncate = 0x20, // Créé le fichier s'il n'existe pas et le vide s'il existe - OpenMode_WriteOnly = 0x40, // Ouvre uniquement en écriture, créé le fichier s'il n'existe pas + OpenMode_Append = 0x01, // Disable writing on existing parts and put the cursor at the end + OpenMode_Lock = 0x02, // Disable modifying the file before it is open + OpenMode_ReadOnly = 0x04, // Open in read only + OpenMode_Text = 0x10, // Open in text mod + OpenMode_Truncate = 0x20, // Create the file if it doesn't exist and empty it if it exists + OpenMode_WriteOnly = 0x40, // Open in write only, create the file if it doesn't exist - OpenMode_ReadWrite = OpenMode_ReadOnly | OpenMode_WriteOnly, // Ouvre en lecture/écriture + OpenMode_ReadWrite = OpenMode_ReadOnly | OpenMode_WriteOnly, // Open in read and write - OpenMode_Max = OpenMode_WriteOnly*2 - 1 + OpenMode_Max = OpenMode_WriteOnly * 2 - 1 }; enum ParameterType @@ -177,7 +177,7 @@ namespace Nz StreamOption_Sequential = 0x1, StreamOption_Text = 0x2, - StreamOption_Max = StreamOption_Text*2 - 1 + StreamOption_Max = StreamOption_Text * 2 - 1 }; enum Ternary diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index 7b97a44e2..d6596dcf2 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -7,7 +7,7 @@ #ifndef NAZARA_OFFSETOF_HPP #define NAZARA_OFFSETOF_HPP -// Par "Jesse Good" de SO: +// By "Jesse Good" from SO: // http://stackoverflow.com/questions/12811330/c-compile-time-offsetof-inside-a-template?answertab=votes#tab-top namespace Nz diff --git a/readme.md b/readme.md index ea7595a96..90a30fda5 100644 --- a/readme.md +++ b/readme.md @@ -45,4 +45,4 @@ Links - **RafBill** and **Raakz:** Finding bugs and/or testing - **Fissal "DrFisher" Hannoun**: Helping a lot in architecture design - **Alexandre "Danman" Janniaux**: Helping making the POSIX implementation -- **Gawaboumga**: Improving the engine code by merging on GitHub +- **Youri "Gawaboumga" Hubaut**: Improving the engine code by merging on GitHub diff --git a/readme_fr.md b/readme_fr.md index bc3364350..fd0f42e7b 100644 --- a/readme_fr.md +++ b/readme_fr.md @@ -45,4 +45,4 @@ Liens - **RafBill** et **Raakz:** Recherche de bugs et/ou tests - **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur - **Alexandre "Danman" Janniaux**: Aide sur l'implémentation POSIX -- **Gawaboumga**: Amélioration du code via le merging sur GitHub +- **Youri "Gawaboumga" Hubaut**: Amélioration du code via le merging sur GitHub From 0a4381a95b4a54f7bb56f5f8cd92aafaa074a8b9 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:41:17 +0100 Subject: [PATCH 123/229] Documentation for Core Former-commit-id: d0d4a575149b9f3e70e07b3a815e669d6a79065f --- include/Nazara/Core/Initializer.inl | 38 +++++++++++++++++++++++++++++ src/Nazara/Core/Core.cpp | 29 +++++++++++++++++++--- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core/Initializer.inl b/include/Nazara/Core/Initializer.inl index cb2529643..cbf613699 100644 --- a/include/Nazara/Core/Initializer.inl +++ b/include/Nazara/Core/Initializer.inl @@ -47,6 +47,16 @@ namespace Nz }; } + /*! + * \class Nz::Initializer + * \brief Core class that represents a module initializer + */ + + /*! + * \brief Constructs a Initializer object with a boolean + * + * \param initialize Initialize the module + */ template Initializer::Initializer(bool initialize) : @@ -56,12 +66,24 @@ namespace Nz Initialize(); } + /*! + * \brief Destructs the object and call Uninitialize + * + * \see Uninitialize + */ + template Initializer::~Initializer() { Uninitialize(); } + /*! + * \brief Initialize the module + * + * \see Uninitialize + */ + template bool Initializer::Initialize() { @@ -71,12 +93,23 @@ namespace Nz return m_initialized; } + /*! + * \brief Checks whether the module is initialized + * \return true if initialized + */ + template bool Initializer::IsInitialized() const { return m_initialized; } + /*! + * \brief Uninitialize the module + * + * \see Initialize + */ + template void Initializer::Uninitialize() { @@ -84,6 +117,11 @@ namespace Nz Detail::Initializer::Uninit(); } + /*! + * \brief Converts the initializer to boolean + * \return true if initialized + */ + template Initializer::operator bool() const { diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 142ffa909..26a451512 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -13,12 +13,24 @@ namespace Nz { + /*! + * \class Nz::CoreCore + * \brief Core class that represents the module initializer of Core + */ + + /*! + * \brief Initializes the Core module + * \return true if initialization is successful + * + * \remark Produces a NazaraNotice + */ + bool Core::Initialize() { if (s_moduleReferenceCounter > 0) { s_moduleReferenceCounter++; - return true; // Déjà initialisé + return true; // Already initialized } s_moduleReferenceCounter++; @@ -29,23 +41,34 @@ namespace Nz return true; } + /*! + * \brief Checks whether the module is initialized + * \return true if module is initialized + */ + bool Core::IsInitialized() { return s_moduleReferenceCounter != 0; } + /*! + * \brief Uninitializes the Core module + * + * \remark Produces a NazaraNotice + */ + void Core::Uninitialize() { if (s_moduleReferenceCounter != 1) { - // Le module est soit encore utilisé, soit pas initialisé + // The module is still in use, or can not be uninitialized if (s_moduleReferenceCounter > 1) s_moduleReferenceCounter--; return; } - // Libération du module + // Free of module s_moduleReferenceCounter = 0; HardwareInfo::Uninitialize(); From 61542b59d6e1c8562c0da4ae196abff2fb71a632 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:41:41 +0100 Subject: [PATCH 124/229] Documentation for Endiannes Former-commit-id: e45c5026b84aa8b354e29d760eff56d13f2dc745 --- include/Nazara/Core/Endianness.hpp | 4 ++-- include/Nazara/Core/Endianness.inl | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp index 62cac093d..44a4e9f26 100644 --- a/include/Nazara/Core/Endianness.hpp +++ b/include/Nazara/Core/Endianness.hpp @@ -11,12 +11,12 @@ #include #if !defined(NAZARA_BIG_ENDIAN) && !defined(NAZARA_LITTLE_ENDIAN) - // Détection automatique selon les macros du compilateur + // Automatic detection following macroes of compiler #if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \ defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__) #define NAZARA_BIG_ENDIAN #elif defined(__i386__) || defined(__i386) || defined(__X86__) || defined (__x86_64) || defined(_M_I86) || \ - defined(_M_IX86) || defined(_M_X64) + defined(_M_IX86) || defined(_M_X64) #define NAZARA_LITTLE_ENDIAN #else #error Failed to identify endianness, you must define either NAZARA_BIG_ENDIAN or NAZARA_LITTLE_ENDIAN diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index 96e4fdf8a..72cb9fc43 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -7,6 +7,11 @@ namespace Nz { + /*! + * \brief Gets the platform endianness + * \return Type of the endianness + */ + inline constexpr Endianness GetPlatformEndianness() { #if defined(NAZARA_BIG_ENDIAN) @@ -16,11 +21,20 @@ namespace Nz #endif } + /*! + * \brief Swaps the byte for endianness operations + * + * \param buffer Raw memory + * \param size Size to change endianness + * + * \remark If size is greather than the preallocated buffer, the behaviour is undefined + */ + inline void SwapBytes(void* buffer, unsigned int size) { UInt8* bytes = reinterpret_cast(buffer); unsigned int i = 0; - unsigned int j = size-1; + unsigned int j = size - 1; while (i < j) std::swap(bytes[i++], bytes[j--]); From b62b694af82fb7b9fb235797dd08f13063ff952e Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:41:58 +0100 Subject: [PATCH 125/229] Documentation for Functor Former-commit-id: d0bac2fa789631c9a56ba5636aa52f260f1cc6fd --- include/Nazara/Core/Functor.hpp | 2 +- include/Nazara/Core/Functor.inl | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core/Functor.hpp b/include/Nazara/Core/Functor.hpp index 994ecc5ae..7ce9995a7 100644 --- a/include/Nazara/Core/Functor.hpp +++ b/include/Nazara/Core/Functor.hpp @@ -9,7 +9,7 @@ #include -// Inspiré du code de la SFML par Laurent Gomila +// Inspired from the of code of the SFML by Laurent Gomila namespace Nz { diff --git a/include/Nazara/Core/Functor.inl b/include/Nazara/Core/Functor.inl index 84ea8e76f..96c22b175 100644 --- a/include/Nazara/Core/Functor.inl +++ b/include/Nazara/Core/Functor.inl @@ -6,18 +6,40 @@ namespace Nz { + /*! + * \class Nz::StdLogger + * \brief Core class that represents a functor + */ + + /*! + * \brief Constructs a FunctorWithoutArgs object with a function + * + * \param func Function to execute + */ + template FunctorWithoutArgs::FunctorWithoutArgs(F func) : m_func(func) { } + /*! + * \brief Runs the function + */ + template void FunctorWithoutArgs::Run() { m_func(); } + /*! + * \brief Constructs a FunctorWithoutArgs object with a function and its arguments + * + * \param func Function to execute + * \param args Arguments for the function + */ + template FunctorWithArgs::FunctorWithArgs(F func, Args&&... args) : m_func(func), @@ -25,12 +47,22 @@ namespace Nz { } + /*! + * \brief Runs the function + */ + template void FunctorWithArgs::Run() { Apply(m_func, m_args); } + /*! + * \brief Constructs a FunctorWithoutArgs object with a member function and an object + * + * \param func Member function to execute + * \param object Object to execute on + */ template MemberWithoutArgs::MemberWithoutArgs(void (C::*func)(), C* object) : @@ -39,6 +71,10 @@ namespace Nz { } + /*! + * \brief Runs the function + */ + template void MemberWithoutArgs::Run() { From 2a28d8863cf0d271650ac144313e0b9c60c51347 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:42:38 +0100 Subject: [PATCH 126/229] Documentation for the rest Former-commit-id: b6f401370127679db397da0039cb5e98477e90db --- include/Nazara/Core/CallOnExit.inl | 27 +++ include/Nazara/Core/Color.inl | 217 +++++++++++++++++++++- include/Nazara/Core/ObjectLibrary.inl | 39 ++++ src/Nazara/Core/Clock.cpp | 2 +- src/Nazara/Core/GuillotineBinPack.cpp | 245 ++++++++++++++++++++++-- src/Nazara/Core/HardwareInfo.cpp | 108 +++++++++-- tests/Engine/Math/AlgorithmMath.cpp | 256 ++++++++++++++++++++++++++ 7 files changed, 851 insertions(+), 43 deletions(-) create mode 100644 tests/Engine/Math/AlgorithmMath.cpp diff --git a/include/Nazara/Core/CallOnExit.inl b/include/Nazara/Core/CallOnExit.inl index f89810a77..987da852e 100644 --- a/include/Nazara/Core/CallOnExit.inl +++ b/include/Nazara/Core/CallOnExit.inl @@ -7,17 +7,38 @@ namespace Nz { + /*! + * \class Nz::CallOnExit + * \brief Core class that represents a function to call at the end of the scope + */ + + /*! + * \brief Constructs a CallOnExit object with a function + * + * \param func Function to call on exit + */ + inline CallOnExit::CallOnExit(Func func) : m_func(func) { } + /*! + * \brief Destructs the object and calls the function + */ + inline CallOnExit::~CallOnExit() { if (m_func) m_func(); } + /*! + * \brief Calls the function and sets the new callback + * + * \param func Function to call on exit + */ + inline void CallOnExit::CallAndReset(Func func) { if (m_func) @@ -26,6 +47,12 @@ namespace Nz Reset(func); } + /*! + * \brief Resets the function + * + * \param func Function to call on exit + */ + inline void CallOnExit::Reset(Func func) { m_func = func; diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index ac576eee3..7dcfc7d75 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -11,10 +11,28 @@ namespace Nz { + /*! + * \class Nz::Color + * \brief Core class that represents a color + */ + + /*! + * \brief Constructs a Color object by default + */ + inline Color::Color() { } + /*! + * \brief Constructs a Color object with values + * + * \param red Red value + * \param green Green value + * \param blue Blue value + * \param alpha Alpha value + */ + inline Color::Color(UInt8 red, UInt8 green, UInt8 blue, UInt8 alpha) : r(red), g(green), @@ -23,6 +41,12 @@ namespace Nz { } + /*! + * \brief Constructs a Color object with a light level + * + * \param lightness Value for r, g and b + */ + inline Color::Color(UInt8 lightness) : r(lightness), g(lightness), @@ -31,6 +55,13 @@ namespace Nz { } + /*! + * \brief Constructs a Color object with values + * + * \param vec[3] vec[0] = red value, vec[1] = green value, vec[2] = blue value + * \param alpha Alpha value + */ + inline Color::Color(UInt8 vec[3], UInt8 alpha) : r(vec[0]), g(vec[1]), @@ -39,6 +70,11 @@ namespace Nz { } + /*! + * \brief Converts this to string + * \return String representation of the object "Color(r, g, b[, a])" + */ + inline String Color::ToString() const { StringStream ss; @@ -52,6 +88,13 @@ namespace Nz return ss; } + /*! + * \brief Adds two colors together + * \return Color which is the sum + * + * \param color Other color + */ + inline Color Color::operator+(const Color& color) const { ///TODO: Improve this shit @@ -64,6 +107,13 @@ namespace Nz return c; } + /*! + * \brief Multiplies two colors together + * \return Color which is the product + * + * \param color Other color + */ + inline Color Color::operator*(const Color& color) const { ///TODO: Improve this shit @@ -76,48 +126,104 @@ namespace Nz return c; } + /*! + * \brief Adds the color to this + * \return Color which is the sum + * + * \param color Other color + */ + inline Color Color::operator+=(const Color& color) { return operator=(operator+(color)); } + /*! + * \brief Multiplies the color to this + * \return Color which is the product + * + * \param color Other color + */ + inline Color Color::operator*=(const Color& color) { return operator=(operator*(color)); } + /*! + * \brief Checks whether the two colors are equal + * \return true if it is the case + * + * \param color Color to compare + */ + inline bool Color::operator==(const Color& color) const { return r == color.r && g == color.g && b == color.b && a == color.a; } + /*! + * \brief Checks whether the two colors are equal + * \return false if it is the case + * + * \param color Color to compare + */ + inline bool Color::operator!=(const Color& color) const { return !operator==(color); } - // Algorithmes venant de http://www.easyrgb.com/index.php?X=MATH + // Algorithm coming from http://www.easyrgb.com/index.php?X=MATH + + /*! + * \brief Converts CMY representation to RGB + * \return Color resulting + * + * \param cyan Cyan component + * \param magenta Magenta component + * \param yellow Yellow component + */ inline Color Color::FromCMY(float cyan, float magenta, float yellow) { return Color(static_cast((1.f-cyan)*255.f), static_cast((1.f-magenta)*255.f), static_cast((1.f-yellow)*255.f)); } + /*! + * \brief Converts CMYK representation to RGB + * \return Color resulting + * + * \param cyan Cyan component + * \param magenta Magenta component + * \param yellow Yellow component + * \param black Black component + */ + inline Color Color::FromCMYK(float cyan, float magenta, float yellow, float black) { return FromCMY(cyan * (1.f - black) + black, - magenta * (1.f - black) + black, - yellow * (1.f - black) + black); + magenta * (1.f - black) + black, + yellow * (1.f - black) + black); } + /*! + * \brief Converts HSL representation to RGB + * \return Color resulting + * + * \param hue Hue component + * \param saturation Saturation component + * \param lightness Lightness component + */ + inline Color Color::FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness) { if (saturation == 0) { // RGB results from 0 to 255 return Color(lightness * 255, - lightness * 255, - lightness * 255); + lightness * 255, + lightness * 255); } else { @@ -135,11 +241,20 @@ namespace Nz float v1 = 2.f * l - v2; return Color(static_cast(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))), - static_cast(255.f * Hue2RGB(v1, v2, h)), - static_cast(255.f * Hue2RGB(v1, v2, h - (1.f/3.f)))); + static_cast(255.f * Hue2RGB(v1, v2, h)), + static_cast(255.f * Hue2RGB(v1, v2, h - (1.f/3.f)))); } } + /*! + * \brief Converts HSV representation to RGB + * \return Color resulting + * + * \param hue Hue component + * \param saturation Saturation component + * \param value Value component + */ + inline Color Color::FromHSV(float hue, float saturation, float value) { if (NumberEquals(saturation, 0.f)) @@ -201,11 +316,28 @@ namespace Nz return Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); } } + + /*! + * \brief Converts XYZ representation to RGB + * \return Color resulting + * + * \param vec Vector3 representing the space color + */ + inline Color Color::FromXYZ(const Vector3f& vec) { return FromXYZ(vec.x, vec.y, vec.z); } + /*! + * \brief Converts XYZ representation to RGB + * \return Color resulting + * + * \param x X component + * \param y Y component + * \param z Z component + */ + inline Color Color::FromXYZ(float x, float y, float z) { x /= 100.f; // X from 0 to 95.047 @@ -234,6 +366,15 @@ namespace Nz return Color(static_cast(r * 255.f), static_cast(g * 255.f), static_cast(b * 255.f)); } + /*! + * \brief Converts RGB representation to CMYK + * + * \param color Color to transform + * \param cyan Cyan component + * \param magenta Magenta component + * \param yellow Yellow component + */ + inline void Color::ToCMY(const Color& color, float* cyan, float* magenta, float* yellow) { *cyan = 1.f - color.r/255.f; @@ -241,6 +382,15 @@ namespace Nz *yellow = 1.f - color.b/255.f; } + /*! + * \brief Converts RGB representation to CMYK + * + * \param color Color to transform + * \param cyan Cyan component + * \param magenta Magenta component + * \param yellow Yellow component + */ + inline void Color::ToCMYK(const Color& color, float* cyan, float* magenta, float* yellow, float* black) { float c, m, y; @@ -265,6 +415,15 @@ namespace Nz *black = k; } + /*! + * \brief Converts RGB representation to HSL + * + * \param color Color to transform + * \param hue Hue component + * \param saturation Saturation component + * \param lightness Lightness component + */ + inline void Color::ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness) { float r = color.r / 255.f; @@ -315,6 +474,15 @@ namespace Nz } } + /*! + * \brief Converts RGB representation to HSV + * + * \param color Color to transform + * \param hue Hue component + * \param saturation Saturation component + * \param value Value component + */ + inline void Color::ToHSV(const Color& color, float* hue, float* saturation, float* value) { float r = color.r / 255.f; @@ -361,11 +529,27 @@ namespace Nz } } + /*! + * \brief Converts RGB representation to XYZ + * + * \param color Color to transform + * \param vec Vector3 representing the space color + */ + inline void Color::ToXYZ(const Color& color, Vector3f* vec) { return ToXYZ(color, &vec->x, &vec->y, &vec->z); } + /*! + * \brief Converts RGB representation to XYZ + * + * \param color Color to transform + * \param x X component + * \param y Y component + * \param z Z component + */ + inline void Color::ToXYZ(const Color& color, float* x, float* y, float* z) { float r = color.r/255.f; //R from 0 to 255 @@ -397,6 +581,15 @@ namespace Nz *z = r*0.0193f + g*0.1192f + b*0.9505f; } + /*! + * \brief Converts HUE representation to RGV + * \return RGB corresponding + * + * \param v1 V1 component + * \param v2 V2 component + * \param vH VH component + */ + inline float Color::Hue2RGB(float v1, float v2, float vH) { if (vH < 0.f) @@ -415,8 +608,16 @@ namespace Nz return v1 + (v2 - v1)*(2.f/3.f - vH)*6; return v1; + } } -} + +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param color The color to output +*/ inline std::ostream& operator<<(std::ostream& out, const Nz::Color& color) { diff --git a/include/Nazara/Core/ObjectLibrary.inl b/include/Nazara/Core/ObjectLibrary.inl index 998adece4..41497a808 100644 --- a/include/Nazara/Core/ObjectLibrary.inl +++ b/include/Nazara/Core/ObjectLibrary.inl @@ -7,6 +7,20 @@ namespace Nz { + /*! + * \class Nz::ObjectRef + * \brief Core class that represents a reference to an object + */ + + /*! + * \brief Gets the ObjectRef object by name + * \return Optional reference + * + * \param name Name of the object + * + * \remark Produces a NazaraError if object not found + */ + template ObjectRef ObjectLibrary::Get(const String& name) { @@ -17,18 +31,37 @@ namespace Nz return ref; } + /*! + * \brief Checks whether the library has the object with that name + * \return true if it the case + */ + template bool ObjectLibrary::Has(const String& name) { return Type::s_library.find(name) != Type::s_library.end(); } + /*! + * \brief Registers the ObjectRef object with that name + * + * \param name Name of the object + * \param object Object to stock + */ + template void ObjectLibrary::Register(const String& name, ObjectRef object) { Type::s_library.emplace(name, object); } + /*! + * \brief Gets the ObjectRef object by name + * \return Optional reference + * + * \param name Name of the object + */ + template ObjectRef ObjectLibrary::Query(const String& name) { @@ -39,6 +72,12 @@ namespace Nz return nullptr; } + /*! + * \brief Unregisters the ObjectRef object with that name + * + * \param name Name of the object + */ + template void ObjectLibrary::Unregister(const String& name) { diff --git a/src/Nazara/Core/Clock.cpp b/src/Nazara/Core/Clock.cpp index dae4c84d5..ef4689d50 100644 --- a/src/Nazara/Core/Clock.cpp +++ b/src/Nazara/Core/Clock.cpp @@ -46,7 +46,7 @@ namespace Nz * \brief Utility class that measure the elapsed time */ - /*! + /*! * \brief Constructs a Clock object * * \param startingValue The starting time value, in microseconds diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 05f8736b5..69e3a1333 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -16,13 +16,36 @@ namespace Nz { + /*! + * \class Nz::GuillotineBinPack + * \brief Core class that represents the "Guillotine problem", combination of the "Bin packing problem" and the "cutting stock" + */ + namespace { + /*! + * \brief Gets the score for fitting the area + * \return Score of the fitting + * + * \param width Width + * \param height Height + * \param freeRectSize Free area + */ + int ScoreBestAreaFit(int width, int height, const Rectui& freeRectSize) { return freeRectSize.width * freeRectSize.height - width * height; } + /*! + * \brief Gets the score for fitting the area following long side + * \return Score of the fitting following long side + * + * \param width Width + * \param height Height + * \param freeRectSize Free area + */ + int ScoreBestLongSideFit(int width, int height, const Rectui& freeRectSize) { int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width)); @@ -32,6 +55,15 @@ namespace Nz return leftover; } + /*! + * \brief Gets the score for fitting the area following short side + * \return Score of the fitting following short side + * + * \param width Width + * \param height Height + * \param freeRectSize Free area + */ + int ScoreBestShortSideFit(int width, int height, const Rectui& freeRectSize) { int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width)); @@ -41,37 +73,85 @@ namespace Nz return leftover; } + /*! + * \brief Gets the worst score for fitting the area + * \return Worst score of the fitting + * + * \param width Width + * \param height Height + * \param freeRectSize Free area + */ + int ScoreWorstAreaFit(int width, int height, const Rectui& freeRectSize) { return -ScoreBestAreaFit(width, height, freeRectSize); } + /*! + * \brief Gets the worst score for fitting the area following long side + * \return Worst score of the fitting following long side + * + * \param width Width + * \param height Height + * \param freeRectSize Free area + */ + int ScoreWorstLongSideFit(int width, int height, const Rectui& freeRectSize) { return -ScoreBestLongSideFit(width, height, freeRectSize); } + /*! + * \brief Gets the worst score for fitting the area following short side + * \return Worst score of the fitting following short side + * + * \param width Width + * \param height Height + * \param freeRectSize Free area + */ + int ScoreWorstShortSideFit(int width, int height, const Rectui& freeRectSize) { return -ScoreBestShortSideFit(width, height, freeRectSize); } } + /*! + * \brief Constructs a GuillotineBinPack object by default + */ + GuillotineBinPack::GuillotineBinPack() { Reset(); } + /*! + * \brief Constructs a GuillotineBinPack object with width and height + * + * \param width Width + * \param height Height + */ + GuillotineBinPack::GuillotineBinPack(unsigned int width, unsigned int height) { Reset(width, height); } + /*! + * \brief Constructs a GuillotineBinPack object with area + * + * \param size Vector2 representing the area (width, height) + */ + GuillotineBinPack::GuillotineBinPack(const Vector2ui& size) { Reset(size); } + /*! + * \brief Clears the content + */ + void GuillotineBinPack::Clear() { m_freeRectangles.clear(); @@ -80,6 +160,15 @@ namespace Nz m_usedArea = 0; } + /*! + * \brief Expands the content + * + * \param newWidth New width for the expansion + * \param newHeight New height for the expansion + * + * \see Expand + */ + void GuillotineBinPack::Expand(unsigned int newWidth, unsigned newHeight) { unsigned int oldWidth = m_width; @@ -98,52 +187,123 @@ namespace Nz while (MergeFreeRectangles()); } + /*! + * \brief Expands the content + * + * \param newSize New area for the expansion + * + * \see Expand + */ + void GuillotineBinPack::Expand(const Vector2ui& newSize) { Expand(newSize.x, newSize.y); } + /*! + * \brief Frees the rectangle + * + * \param rect Area to free + * + * \remark This method should only be called with computed rectangles by the method Insert and can produce fragmentation + */ + void GuillotineBinPack::FreeRectangle(const Rectui& rect) { - ///DOC: Cette méthode ne devrait recevoir que des rectangles calculés par la méthode Insert et peut provoquer de la fragmentation m_freeRectangles.push_back(rect); m_usedArea -= rect.width * rect.height; } + /*! + * \brief Gets the height + * \return Height of the area + */ + unsigned int GuillotineBinPack::GetHeight() const { return m_height; } + /*! + * \brief Gets percentage of occupation + * \return Percentage of the already occupied area + */ + float GuillotineBinPack::GetOccupancy() const { return static_cast(m_usedArea)/(m_width*m_height); } + /*! + * \brief Gets the size of the area + * \return Size of the area + */ + Vector2ui GuillotineBinPack::GetSize() const { return Vector2ui(m_width, m_height); } + /*! + * \brief Gets the width + * \return Width of the area + */ + unsigned int GuillotineBinPack::GetWidth() const { return m_width; } + /*! + * \brief Inserts rectangles in the area + * \return true if each rectangle could be inserted + * + * \param rects List of rectangles + * \param count Count of rectangles + * \param merge Merge possible + * \param rectChoice Heuristic to use to free + * \param splitMethod Heuristic to use to split + */ + bool GuillotineBinPack::Insert(Rectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) { return Insert(rects, nullptr, nullptr, count, merge, rectChoice, splitMethod); } + /*! + * \brief Inserts rectangles in the area + * \return true if each rectangle could be inserted + * + * \param rects List of rectangles + * \param flipped List of flipped rectangles + * \param count Count of rectangles + * \param merge Merge possible + * \param rectChoice Heuristic to use to free + * \param splitMethod Heuristic to use to split + */ + bool GuillotineBinPack::Insert(Rectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) { return Insert(rects, flipped, nullptr, count, merge, rectChoice, splitMethod); } + /*! + * \brief Inserts rectangles in the area + * \return true if each rectangle could be inserted + * + * \param rects List of rectangles + * \param flipped List of flipped rectangles + * \param flipped List of inserted rectangles + * \param count Count of rectangles + * \param merge Merge possible + * \param rectChoice Heuristic to use to free + * \param splitMethod Heuristic to use to split + */ + bool GuillotineBinPack::Insert(Rectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) { - std::vector remainingRects(count); // La position du rectangle + std::vector remainingRects(count); // Position of the rectangle for (unsigned int i = 0; i < count; ++i) remainingRects[i] = &rects[i]; @@ -214,7 +374,7 @@ namespace Nz // If we didn't manage to find any rectangle to pack, abort. if (bestScore == std::numeric_limits::max()) { - // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés + // If we can do it, we mark the rectangle could be inserted if (inserted) { for (Rectui* rect : remainingRects) @@ -259,9 +419,13 @@ namespace Nz return true; } + /*! + * \brief Merges free rectangles together + * \return true if there was a merge (and thus if a merge is still possible) + */ + bool GuillotineBinPack::MergeFreeRectangles() { - ///DOC: Renvoie true s'il y a eu fusion (et donc si une fusion est encore possible) std::size_t oriSize = m_freeRectangles.size(); // Do a Theta(n^2) loop to see if any pair of free rectangles could me merged into one. @@ -312,6 +476,10 @@ namespace Nz return m_freeRectangles.size() < oriSize; } + /*! + * \brief Resets the area + */ + void GuillotineBinPack::Reset() { m_height = 0; @@ -320,6 +488,13 @@ namespace Nz Clear(); } + /*! + * \brief Resets the area + * + * \param width Width + * \param height Height + */ + void GuillotineBinPack::Reset(unsigned int width, unsigned int height) { m_height = height; @@ -328,11 +503,25 @@ namespace Nz Clear(); } + /*! + * \brief Resets the area + * + * \param size Size of the area + */ + void GuillotineBinPack::Reset(const Vector2ui& size) { Reset(size.x, size.y); } + /*! + * \brief Splits the free rectangle along axis + * + * \param freeRect Free rectangle to split + * \param placedRect Already placed rectangle + * \param splitHorizontal Split horizontally (or vertically) + */ + void GuillotineBinPack::SplitFreeRectAlongAxis(const Rectui& freeRect, const Rectui& placedRect, bool splitHorizontal) { // Form the two new rectangles. @@ -365,50 +554,60 @@ namespace Nz m_freeRectangles.push_back(right); } + /*! + * \brief Splits the free rectangle using the heuristic + * + * \param freeRect Free rectangle to split + * \param placedRect Already placed rectangle + * \param method Method used to split + * + * \remark Produces a NazaraError if enumeration GuillotineSplitHeuristic is invalid + */ + void GuillotineBinPack::SplitFreeRectByHeuristic(const Rectui& freeRect, const Rectui& placedRect, GuillotineSplitHeuristic method) { - // Compute the lengths of the leftover area. + // Compute the lengths of the leftover area const int w = freeRect.width - placedRect.width; const int h = freeRect.height - placedRect.height; // Placing placedRect into freeRect results in an L-shaped free area, which must be split into - // two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line. - // We have two choices: horizontal or vertical. + // two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line + // We have two choices: horizontal or vertical - // Use the given heuristic to decide which choice to make. + // Use the given heuristic to decide which choice to make bool splitHorizontal; switch (method) { case SplitLongerAxis: - // Split along the longer total axis. + // Split along the longer total axis splitHorizontal = (freeRect.width > freeRect.height); break; case SplitLongerLeftoverAxis: - // Split along the longer leftover axis. + // Split along the longer leftover axis splitHorizontal = (w > h); break; case SplitMaximizeArea: - // Maximize the smaller area == minimize the larger area. - // Tries to make the rectangles more even-sized. + // Maximize the smaller area == minimize the larger area + // Tries to make the rectangles more even-sized splitHorizontal = (placedRect.width * h <= w * placedRect.height); break; case SplitMinimizeArea: - // Maximize the larger area == minimize the smaller area. - // Tries to make the single bigger rectangle. + // Maximize the larger area == minimize the smaller area + // Tries to make the single bigger rectangle splitHorizontal = (placedRect.width * h > w * placedRect.height); break; case SplitShorterAxis: - // Split along the shorter total axis. + // Split along the shorter total axis splitHorizontal = (freeRect.width <= freeRect.height); break; case SplitShorterLeftoverAxis: - // Split along the shorter leftover axis. + // Split along the shorter leftover axis splitHorizontal = (w <= h); break; @@ -417,10 +616,22 @@ namespace Nz splitHorizontal = true; } - // Perform the actual split. + // Perform the actual split SplitFreeRectAlongAxis(freeRect, placedRect, splitHorizontal); } + /*! + * \brief Gets the score using heuristic + * \return Score of the heuristic + * + * \param width Width + * \param height Height + * \param freeRect Free area + * \param rectChoice Heuristic to get score + * + * \remark Produces a NazaraError if enumeration FreeRectChoiceHeuristic is invalid + */ + int GuillotineBinPack::ScoreByHeuristic(int width, int height, const Rectui& freeRect, FreeRectChoiceHeuristic rectChoice) { switch (rectChoice) diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index 1ada7a794..af7f47e5d 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -82,11 +82,31 @@ namespace Nz char s_brandString[48] = "Not initialized"; } + /*! + * \class Nz::HardwareInfo + * \brief Core class that represents the info we can get from hardware + */ + + /*! + * \brief Generates the cpuid instruction (available on x86 & x64) + * + * \param functionId Information to retrieve + * \param subFunctionId Additional code for information retrieval + * \param result Supported features of the CPU + */ + void HardwareInfo::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 result[4]) { return HardwareInfoImpl::Cpuid(functionId, subFunctionId, result); } + /*! + * \brief Gets the brand of the processor + * \return String of the brand + * + * \remark Produces a NazaraError if not Initialize + */ + String HardwareInfo::GetProcessorBrandString() { if (!Initialize()) @@ -95,13 +115,26 @@ namespace Nz return s_brandString; } + /*! + * \brief Gets the number of threads + * \return Number of threads available on the CPU + * + * \remark Doesn't need the initialization of HardwareInfo + */ + unsigned int HardwareInfo::GetProcessorCount() { - ///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner static unsigned int processorCount = std::max(HardwareInfoImpl::GetProcessorCount(), 1U); return processorCount; } + /*! + * \brief Gets the processor vendor + * \return ProcessorVendor containing information the vendor + * + * \remark Produces a NazaraError if not Initialize + */ + ProcessorVendor HardwareInfo::GetProcessorVendor() { if (!Initialize()) @@ -110,6 +143,13 @@ namespace Nz return s_vendorEnum; } + /*! + * \brief Gets the vendor of the processor + * \return String of the vendor + * + * \remark Produces a NazaraError if not Initialize + */ + String HardwareInfo::GetProcessorVendorName() { if (!Initialize()) @@ -118,13 +158,26 @@ namespace Nz return vendorNames[s_vendorEnum+1]; } + /*! + * \brief Gets the amount of total memory + * \return Number of total memory available + * + * \remark Doesn't need the initialization of HardwareInfo + */ + UInt64 HardwareInfo::GetTotalMemory() { - ///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner static UInt64 totalMemory = HardwareInfoImpl::GetTotalMemory(); return totalMemory; } + /*! + * \brief Checks whether the processor owns the capacity to handle certain instructions + * \return true If instructions supported + * + * \remark Produces a NazaraError if capability is a wrong enum with NAZARA_DEBUG defined + */ + bool HardwareInfo::HasCapability(ProcessorCap capability) { #ifdef NAZARA_DEBUG @@ -138,9 +191,16 @@ namespace Nz return s_capabilities[capability]; } + /*! + * \brief Initializes the HardwareInfo class + * \return true if successful + * + * \remark Produces a NazaraError if cpuid is not supported + */ + bool HardwareInfo::Initialize() { - if (s_initialized) + if (IsInitialized()) return true; if (!HardwareInfoImpl::IsCpuidSupported()) @@ -151,21 +211,21 @@ namespace Nz s_initialized = true; - UInt32 registers[4]; // Récupère les quatre registres (EAX, EBX, ECX et EDX) + UInt32 registers[4]; // Get the four registers (EAX, EBX, ECX et EDX) - // Pour plus de clarté + // To make it more clear UInt32& eax = registers[0]; UInt32& ebx = registers[1]; UInt32& ecx = registers[2]; UInt32& edx = registers[3]; - // Pour commencer, on va récupérer l'identifiant du constructeur ainsi que l'id de fonction maximal supporté par le CPUID + // To begin, we get the id of the constructor and the id of maximal functions supported by the CPUID HardwareInfoImpl::Cpuid(0, 0, registers); - // Attention à l'ordre : EBX, EDX, ECX + // Watchout to the order : EBX, EDX, ECX UInt32 manufacturerId[3] = {ebx, edx, ecx}; - // Identification du concepteur + // Identification of conceptor s_vendorEnum = ProcessorVendor_Unknown; for (const VendorString& vendorString : vendorStrings) { @@ -178,7 +238,7 @@ namespace Nz if (eax >= 1) { - // Récupération de certaines capacités du processeur (ECX et EDX, fonction 1) + // Recuperation of certain capacities of the processor (ECX et EDX, function 1) HardwareInfoImpl::Cpuid(1, 0, registers); s_capabilities[ProcessorCap_AVX] = (ecx & (1U << 28)) != 0; @@ -192,53 +252,67 @@ namespace Nz s_capabilities[ProcessorCap_SSE42] = (ecx & (1U << 20)) != 0; } - // Récupération de la plus grande fonction étendue supportée (EAX, fonction 0x80000000) + // Recuperation of biggest extended function handled (EAX, fonction 0x80000000) HardwareInfoImpl::Cpuid(0x80000000, 0, registers); UInt32 maxSupportedExtendedFunction = eax; if (maxSupportedExtendedFunction >= 0x80000001) { - // Récupération des capacités étendues du processeur (ECX et EDX, fonction 0x80000001) + // Recuperation of extended capabilities of the processor (ECX et EDX, fonction 0x80000001) HardwareInfoImpl::Cpuid(0x80000001, 0, registers); - s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support du 64bits, indépendant de l'OS + s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support of 64bits, independant of the OS s_capabilities[ProcessorCap_FMA4] = (ecx & (1U << 16)) != 0; s_capabilities[ProcessorCap_SSE4a] = (ecx & (1U << 6)) != 0; s_capabilities[ProcessorCap_XOP] = (ecx & (1U << 11)) != 0; if (maxSupportedExtendedFunction >= 0x80000004) { - // Récupération d'une chaîne de caractère décrivant le processeur (EAX, EBX, ECX et EDX, - // fonctions de 0x80000002 à 0x80000004 compris) + // Recuperation of the string describing the processor (EAX, EBX, ECX et EDX, + // functions from 0x80000002 to 0x80000004 inclusive) char* ptr = &s_brandString[0]; for (UInt32 code = 0x80000002; code <= 0x80000004; ++code) { HardwareInfoImpl::Cpuid(code, 0, registers); - std::memcpy(ptr, ®isters[0], 4*sizeof(UInt32)); // On rajoute les 16 octets à la chaîne + std::memcpy(ptr, ®isters[0], 4*sizeof(UInt32)); // We add the 16 bytes to the string ptr += 4*sizeof(UInt32); } - // Le caractère nul faisant partie de la chaîne retournée par le CPUID, pas besoin de le rajouter + // The character '\0' is already returned } } return true; } + /*! + * \brief Checks whether the instruction of cpuid is supported + * \return true if it the case + */ + bool HardwareInfo::IsCpuidSupported() { return HardwareInfoImpl::IsCpuidSupported(); } + /*! + * \brief Checks whether the class HardwareInfo is initialized + * \return true if it is initialized + */ + bool HardwareInfo::IsInitialized() { return s_initialized; } + /*! + * \brief Unitializes the class HardwareInfo + */ + void HardwareInfo::Uninitialize() { - // Rien à faire + // Nothing to do s_initialized = false; } } diff --git a/tests/Engine/Math/AlgorithmMath.cpp b/tests/Engine/Math/AlgorithmMath.cpp new file mode 100644 index 000000000..01413d902 --- /dev/null +++ b/tests/Engine/Math/AlgorithmMath.cpp @@ -0,0 +1,256 @@ +#include +#include + +TEST_CASE("Approach", "[MATH][ALGORITHM]") +{ + SECTION("Approach 8 with 5 by 2") + { + REQUIRE(Nz::Approach(5, 8, 2) == 7); + } + + SECTION("Approach 5 with 8 by 2") + { + REQUIRE(Nz::Approach(8, 5, 2) == 6); + } + + SECTION("Approach 8 with 8 by 2") + { + REQUIRE(Nz::Approach(8, 8, 2) == 8); + } +} + +TEST_CASE("Clamp", "[MATH][ALGORITHM]") +{ + SECTION("Clamp 8 between 5 and 10") + { + REQUIRE(Nz::Clamp(8, 5, 10) == 8); + } + + SECTION("Clamp 4 between 5 and 10") + { + REQUIRE(Nz::Clamp(4, 5, 10) == 5); + } + + SECTION("Clamp 12 between 5 and 10") + { + REQUIRE(Nz::Clamp(12, 5, 10) == 10); + } +} + +TEST_CASE("CountBits", "[MATH][ALGORITHM]") +{ + SECTION("Number 10 has 2 bits set to 1") + { + REQUIRE(Nz::CountBits(10) == 2); + } + + SECTION("Number 0 has 0 bit set to 1") + { + REQUIRE(Nz::CountBits(0) == 0); + } +} + +TEST_CASE("DegreeToRadian", "[MATH][ALGORITHM]") +{ + SECTION("Convert 45.f degree to radian") + { + REQUIRE(Nz::DegreeToRadian(45.f) == Approx(M_PI / 4)); + } +} + +TEST_CASE("GetNearestPowerOfTwo", "[MATH][ALGORITHM]") +{ + SECTION("Nearest power of two of 0 = 1") + { + REQUIRE(Nz::GetNearestPowerOfTwo(0) == 1); + } + + SECTION("Nearest power of two of 16 = 16") + { + REQUIRE(Nz::GetNearestPowerOfTwo(16) == 16); + } + + SECTION("Nearest power of two of 17 = 32") + { + REQUIRE(Nz::GetNearestPowerOfTwo(17) == 32); + } +} + +TEST_CASE("GetNumberLength", "[MATH][ALGORITHM]") +{ + SECTION("GetNumberLength of -127 signed char") + { + signed char minus127 = -127; + REQUIRE(Nz::GetNumberLength(minus127) == 4); + } + + SECTION("GetNumberLength of 255 unsigned char") + { + unsigned char plus255 = 255; + REQUIRE(Nz::GetNumberLength(plus255) == 3); + } + + SECTION("GetNumberLength of -1270 signed int") + { + signed int minus1270 = -1270; + REQUIRE(Nz::GetNumberLength(minus1270) == 5); + } + + SECTION("GetNumberLength of 2550 unsigned int") + { + unsigned int plus2550 = 2550; + REQUIRE(Nz::GetNumberLength(plus2550) == 4); + } + + SECTION("GetNumberLength of -1270 signed long long") + { + signed long long minus12700 = -12700; + REQUIRE(Nz::GetNumberLength(minus12700) == 6); + } + + SECTION("GetNumberLength of 2550 unsigned long long") + { + unsigned long long plus25500 = 25500; + REQUIRE(Nz::GetNumberLength(plus25500) == 5); + } + + SECTION("GetNumberLength of -2.456f float") + { + float minus2P456 = -2.456f; + REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); + } + + SECTION("GetNumberLength of -2.456 double") + { + double minus2P456 = -2.456; + REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); + } + + SECTION("GetNumberLength of -2.456 long double") + { + long double minus2P456 = -2.456L; + REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); + } +} + +TEST_CASE("IntegralLog2", "[MATH][ALGORITHM]") +{ + SECTION("According to implementation, log in base 2 of 0 = 0") + { + REQUIRE(Nz::IntegralLog2(0) == 0); + } + + SECTION("Log in base 2 of 1 = 0") + { + REQUIRE(Nz::IntegralLog2(1) == 0); + } + + SECTION("Log in base 2 of 4 = 2") + { + REQUIRE(Nz::IntegralLog2(4) == 2); + } + + SECTION("Log in base 2 of 5 = 2") + { + REQUIRE(Nz::IntegralLog2(5) == 2); + } +} + +TEST_CASE("IntegralLog2Pot", "[MATH][ALGORITHM]") +{ + SECTION("According to implementation, log in base 2 of 0 = 0") + { + REQUIRE(Nz::IntegralLog2Pot(0) == 0); + } + + SECTION("Log in base 2 of 1 = 0") + { + REQUIRE(Nz::IntegralLog2Pot(1) == 0); + } + + SECTION("Log in base 2 of 4 = 2") + { + REQUIRE(Nz::IntegralLog2Pot(4) == 2); + } +} + +TEST_CASE("IntegralPow", "[MATH][ALGORITHM]") +{ + SECTION("2 to power 4") + { + REQUIRE(Nz::IntegralPow(2, 4) == 16); + } +} + +TEST_CASE("Lerp", "[MATH][ALGORITHM]") +{ + SECTION("Lerp 2 to 6 with 0.5") + { + REQUIRE(Nz::Lerp(2, 6, 0.5) == 4); + } +} + +TEST_CASE("MultiplyAdd", "[MATH][ALGORITHM]") +{ + SECTION("2 * 3 + 1") + { + REQUIRE(Nz::MultiplyAdd(2, 3, 1) == 7); + } +} + +TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") +{ + SECTION("2.35 and 2.351 should be the same at 0.01") + { + CHECK(Nz::NumberEquals(2.35, 2.35, 0.01)); + } + + SECTION("3 and 4 unsigned should be the same at 1") + { + CHECK(Nz::NumberEquals(3U, 4U, 1U)); + } +} + +TEST_CASE("NumberToString", "[MATH][ALGORITHM]") +{ + SECTION("235 to string") + { + REQUIRE(Nz::NumberToString(235) == "235"); + } + + SECTION("-235 to string") + { + REQUIRE(Nz::NumberToString(-235) == "-235"); + } + + SECTION("16 in base 16 to string") + { + REQUIRE(Nz::NumberToString(16, 16) == "10"); + } +} + +TEST_CASE("RadianToDegree", "[MATH][ALGORITHM]") +{ + SECTION("PI / 4 to degree") + { + REQUIRE(Nz::RadianToDegree(M_PI / 4) == Approx(45.f)); + } +} + +TEST_CASE("StringToNumber", "[MATH][ALGORITHM]") +{ + SECTION("235 in string") + { + REQUIRE(Nz::StringToNumber("235") == 235); + } + + SECTION("-235 in string") + { + REQUIRE(Nz::StringToNumber("-235") == -235); + } + + SECTION("16 in base 16 in string") + { + REQUIRE(Nz::StringToNumber("10", 16) == 16); + } +} From de59eb1f74a6414577702c07f37bf6c48ece9015 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Sun, 21 Feb 2016 14:50:01 +0100 Subject: [PATCH 127/229] Delete notice in Display Former-commit-id: d3ddf65b5f00af047b4232068553363d88d3ca30 --- src/Nazara/Utility/X11/Display.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Nazara/Utility/X11/Display.cpp b/src/Nazara/Utility/X11/Display.cpp index 2ec41ff0d..63fbb65ac 100644 --- a/src/Nazara/Utility/X11/Display.cpp +++ b/src/Nazara/Utility/X11/Display.cpp @@ -136,7 +136,6 @@ namespace Nz OpenEWMHConnection(sharedConnection); } - NazaraNotice("Initialized: Display module"); return true; } @@ -208,8 +207,6 @@ namespace Nz xcb_disconnect(sharedConnection); } - - NazaraNotice("Uninitialized: Display module"); } xcb_window_t X11::XCBDefaultRootWindow(xcb_connection_t* connection) From dff6e855e49f7640fd8b616f45c66488a0b45c65 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:12:45 +0100 Subject: [PATCH 128/229] Fixes compilation on GCC Former-commit-id: 1829fa37830618bd9b14e7bfa5d935c886213589 --- include/Nazara/Core/ByteArray.inl | 4 ++++ include/Nazara/Lua/LuaInstance.inl | 3 ++- src/Nazara/Graphics/Formats/OBJLoader.cpp | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 1597758fd..a21835f4e 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -3,6 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include namespace Nz { @@ -356,3 +358,5 @@ namespace std lhs.Swap(rhs); } } + +#include diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index c7f72df34..bea66215c 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -2,11 +2,12 @@ // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include +#include #include #include #include -#include "LuaInstance.hpp" namespace Nz { diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Graphics/Formats/OBJLoader.cpp index b295811d4..a81acae1b 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include From d6279914b4a9f6a5bf747548a27af4a792fc38d4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:14:29 +0100 Subject: [PATCH 129/229] Network/Socket: Fix last error being undefined without any operation Former-commit-id: 5ccd098d93842f0be79d516630f39150a394045c --- include/Nazara/Network/AbstractSocket.hpp | 4 ++-- src/Nazara/Network/AbstractSocket.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index 5bd91d807..f3789ebf0 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -44,14 +44,14 @@ namespace Nz protected: AbstractSocket(SocketType type); - inline void UpdateState(SocketState newState); - virtual void OnClose(); virtual void OnOpened(); bool Open(NetProtocol protocol); void Open(SocketHandle existingHandle); + inline void UpdateState(SocketState newState); + NetProtocol m_protocol; SocketError m_lastError; SocketHandle m_handle; diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index bec0cdf84..e46a5906a 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -18,6 +18,7 @@ namespace Nz { AbstractSocket::AbstractSocket(SocketType type) : + m_lastError(SocketError_NoError), m_handle(SocketImpl::InvalidHandle), m_state(SocketState_NotConnected), m_type(type), From a851056c0a336b35742a5d1da60900d197028930 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:17:28 +0100 Subject: [PATCH 130/229] Network/Packet: Fixes buffer size Former-commit-id: 51fd56f76af8abe8feb1ed88802ef7ec0bd4a175 --- include/Nazara/Network/NetPacket.hpp | 7 ++++--- include/Nazara/Network/NetPacket.inl | 16 ++++++++++++---- src/Nazara/Network/NetPacket.cpp | 7 +++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index 83815b0fe..bbd5a750b 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -22,7 +22,7 @@ namespace Nz public: inline NetPacket(); - inline NetPacket(UInt16 netCode, std::size_t minSize = 0); + inline NetPacket(UInt16 netCode, std::size_t minCapacity = 0); inline NetPacket(UInt16 netCode, const void* ptr, std::size_t size); NetPacket(const NetPacket&) = delete; NetPacket(NetPacket&&) = default; @@ -30,13 +30,14 @@ namespace Nz inline const UInt8* GetConstData() const; inline UInt8* GetData() const; + inline size_t GetDataSize() const; inline UInt16 GetNetCode() const; virtual void OnReceive(UInt16 netCode, const void* data, std::size_t size); virtual const void* OnSend(std::size_t* newSize) const; inline void Reset(); - inline void Reset(UInt16 netCode, std::size_t minSize = 0); + inline void Reset(UInt16 netCode, std::size_t minCapacity = 0); inline void Reset(UInt16 netCode, const void* ptr, std::size_t size); inline void Resize(std::size_t newSize); @@ -55,7 +56,7 @@ namespace Nz void OnEmptyStream() override; void FreeStream(); - void InitStream(std::size_t minSize, UInt64 cursorPos, UInt32 openMode); + void InitStream(std::size_t minCapacity, UInt64 cursorPos, UInt32 openMode); static bool Initialize(); static void Uninitialize(); diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index 1fdf6c6ee..d21f9a3db 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -14,9 +14,9 @@ namespace Nz { } - inline NetPacket::NetPacket(UInt16 netCode, std::size_t minSize) + inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity) { - Reset(netCode, minSize); + Reset(netCode, minCapacity); } inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) @@ -44,6 +44,14 @@ namespace Nz return m_buffer->GetBuffer(); } + inline size_t NetPacket::GetDataSize() const + { + if (m_buffer) + return m_buffer->GetSize() - HeaderSize; + else + return 0; + } + inline UInt16 NetPacket::GetNetCode() const { return m_netCode; @@ -54,9 +62,9 @@ namespace Nz FreeStream(); } - inline void NetPacket::Reset(UInt16 netCode, std::size_t minSize) + inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity) { - InitStream(HeaderSize + minSize, HeaderSize, OpenMode_ReadWrite); + InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite); m_netCode = netCode; } diff --git a/src/Nazara/Network/NetPacket.cpp b/src/Nazara/Network/NetPacket.cpp index e0c5b3df8..7a1c0d7f5 100644 --- a/src/Nazara/Network/NetPacket.cpp +++ b/src/Nazara/Network/NetPacket.cpp @@ -66,9 +66,9 @@ namespace Nz s_availableBuffers.emplace_back(std::make_pair(size, std::move(m_buffer))); } - void NetPacket::InitStream(std::size_t minSize, UInt64 cursorPos, UInt32 openMode) + void NetPacket::InitStream(std::size_t minCapacity, UInt64 cursorPos, UInt32 openMode) { - NazaraAssert(minSize >= cursorPos, "Cannot init stream with a smaller size than wanted cursor pos"); + NazaraAssert(minCapacity >= cursorPos, "Cannot init stream with a smaller capacity than wanted cursor pos"); { Nz::LockGuard lock(*s_availableBuffersMutex); @@ -85,8 +85,7 @@ namespace Nz if (!m_buffer) m_buffer = std::make_unique(); - if (m_buffer->GetSize() < minSize) - m_buffer->Resize(minSize); + m_buffer->Resize(static_cast(cursorPos)); m_memoryStream.SetBuffer(m_buffer.get(), openMode); m_memoryStream.SetCursorPos(cursorPos); From d24de1f719ef133b2b93178cb971d913ffac973b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:17:47 +0100 Subject: [PATCH 131/229] Network/NetPacket: Add move constructor/operator Former-commit-id: 56cb793ab75e5bcd97b89c5be3592922c23a7a4d --- include/Nazara/Network/NetPacket.hpp | 4 ++-- include/Nazara/Network/NetPacket.inl | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index bbd5a750b..272808a33 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -25,7 +25,7 @@ namespace Nz inline NetPacket(UInt16 netCode, std::size_t minCapacity = 0); inline NetPacket(UInt16 netCode, const void* ptr, std::size_t size); NetPacket(const NetPacket&) = delete; - NetPacket(NetPacket&&) = default; + NetPacket(NetPacket&& packet); inline ~NetPacket(); inline const UInt8* GetConstData() const; @@ -45,7 +45,7 @@ namespace Nz inline void SetNetCode(UInt16 netCode); NetPacket& operator=(const NetPacket&) = delete; - NetPacket& operator=(NetPacket&&) = default; + NetPacket& operator=(NetPacket&& packet); static bool DecodeHeader(const void* data, UInt16* packetSize, UInt16* netCode); static bool EncodeHeader(void* data, UInt16 packetSize, UInt16 netCode); diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index d21f9a3db..c9bbed681 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -24,6 +24,17 @@ namespace Nz Reset(netCode, ptr, size); } + inline NetPacket::NetPacket(NetPacket&& packet) : + ByteStream(std::move(packet)), + m_buffer(std::move(packet.m_buffer)), + m_memoryStream(std::move(packet.m_memoryStream)), + m_netCode(packet.m_netCode) + { + ///< Redirect memory stream to the moved buffer + m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode()); + SetStream(&m_memoryStream); + } + inline NetPacket::~NetPacket() { FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it @@ -88,6 +99,23 @@ namespace Nz { m_netCode = netCode; } + + inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet) + { + FreeStream(); + + ByteStream::operator=(std::move(packet)); + + m_buffer = std::move(packet.m_buffer); + m_memoryStream = std::move(packet.m_memoryStream); + m_netCode = packet.m_netCode; + + ///< Redirect memory stream to the moved buffer + m_memoryStream.SetBuffer(m_buffer.get(), m_memoryStream.GetOpenMode()); + SetStream(&m_memoryStream); + + return *this; + } } #include From a0a088a9149abdd08f51d2ae557aed487f1b791a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:18:22 +0100 Subject: [PATCH 132/229] Network/UdpSocket: Fix receiving packet Former-commit-id: f27235940770d8e818fa1b60b4840be88cb04fd0 --- src/Nazara/Network/UdpSocket.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index d8461c627..a233881ea 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -67,13 +67,11 @@ namespace Nz // I'm not sure what's the best between having a 65k bytes buffer ready for any datagram size // or querying the next datagram size every time, for now I'll leave it as is packet->Reset(NetCode_Invalid, std::numeric_limits::max()); + packet->Resize(std::numeric_limits::max()); std::size_t received; if (!Receive(packet->GetData(), static_cast(packet->GetSize()), from, &received)) - { - NazaraError("Failed to receive packet"); return false; - } if (received == 0) return false; //< No datagram received From 9d4256a4d2699772261ba867aa910140be8b089b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:19:03 +0100 Subject: [PATCH 133/229] Network/TcpClient: Fix disconnection of previous connection not happening with IP connection Former-commit-id: 3ec17a6c56ee3f0aae7f66f78766f15d7a168f32 --- src/Nazara/Network/TcpClient.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 267e5f67a..5b31b6bd5 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -25,6 +25,7 @@ namespace Nz NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); + Disconnect(); Open(remoteAddress.GetProtocol()); CallOnExit restoreBlocking; @@ -46,8 +47,6 @@ namespace Nz SocketState TcpClient::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error) { - Disconnect(); - UpdateState(SocketState_Resolving); std::vector results = IpAddress::ResolveHostname(protocol, hostName, service, error); if (results.empty()) From ff25505d92dff4f7cc28249b93e45d3bb775b5e9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 14:19:15 +0100 Subject: [PATCH 134/229] Network: Remove outdated comment Former-commit-id: 454debf692483a58ea5a24cbaa6ecf2a8715a242 --- src/Nazara/Network/Win32/IpAddressImpl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index b23ceae04..9f3918574 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -191,7 +191,6 @@ namespace Nz Detail::FreeAddressInfo(servinfo); }); - // loop through all the results and connect to the first we can for (Detail::addrinfoImpl* p = servinfo; p != nullptr; p = p->ai_next) { HostnameInfo result; From e9bb81e85178aea495a8668dfbe74caa92944972 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 24 Feb 2016 17:09:40 +0100 Subject: [PATCH 135/229] Utility/Algorithm: Fix crash in ComputeAABB Former-commit-id: 58266814fea559c782e6df1145f82a37baf0427c --- src/Nazara/Utility/AlgorithmUtility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index d22021cd2..0b674c248 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -636,7 +636,7 @@ namespace Nz if (vertexCount > 0) { aabb.Set(positionPtr->x, positionPtr->y, positionPtr->z, 0.f, 0.f, 0.f); - --positionPtr; + ++positionPtr; for (unsigned int i = 1; i < vertexCount; ++i) aabb.ExtendTo(*positionPtr++); From 790275da8f6a0e1c2382e30c0b6a304d67d4a3e9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 13:58:45 +0100 Subject: [PATCH 136/229] Tests: Fix compile error Former-commit-id: b677c9073998d1449c7aa955e100b53f6931e7f0 --- tests/Engine/Core/AbstractHash.cpp | 2 +- tests/Engine/Core/PrimitiveList.cpp | 15 +- tests/Engine/Core/SparsePtr.cpp | 2 +- tests/Engine/Math/Algorithm.cpp | 256 ---------------------------- 4 files changed, 16 insertions(+), 259 deletions(-) delete mode 100644 tests/Engine/Math/Algorithm.cpp diff --git a/tests/Engine/Core/AbstractHash.cpp b/tests/Engine/Core/AbstractHash.cpp index bcb47fc33..f5ee57d30 100644 --- a/tests/Engine/Core/AbstractHash.cpp +++ b/tests/Engine/Core/AbstractHash.cpp @@ -15,7 +15,7 @@ SCENARIO("AbstractHash", "[CORE][ABSTRACTHASH]") WHEN("We introduce data") { std::array array{ 0, 1, 2, 3 }; - SHA512->Append(array.begin(), array.size()); + SHA512->Append(array.data(), array.size()); THEN("We ask for the bytearray") { diff --git a/tests/Engine/Core/PrimitiveList.cpp b/tests/Engine/Core/PrimitiveList.cpp index 84a39cac2..e0098a75e 100644 --- a/tests/Engine/Core/PrimitiveList.cpp +++ b/tests/Engine/Core/PrimitiveList.cpp @@ -15,17 +15,30 @@ SCENARIO("PrimitiveList", "[CORE][PRIMITIVELIST]") Nz::Matrix4f identity = Nz::Matrix4f::Identity(); primitiveList.AddCubicSphere(size, subdivision, identity); + primitiveList.AddBox(Nz::Vector3f(size), Nz::Vector3ui(subdivision), identity); primitiveList.AddIcoSphere(size, subdivision, identity); THEN("There must be two items") { - REQUIRE(primitiveList.GetSize() == 2); + REQUIRE(primitiveList.GetSize() == 3); } THEN("The first one is the cubic sphere") { + REQUIRE(primitiveList(0).type == Nz::PrimitiveType_Sphere); REQUIRE(primitiveList(0).sphere.type == Nz::SphereType_Cubic); } + + THEN("The second one is the box") + { + REQUIRE(primitiveList(1).type == Nz::PrimitiveType_Box); + } + + THEN("The third one is the ico sphere") + { + REQUIRE(primitiveList(2).type == Nz::PrimitiveType_Sphere); + REQUIRE(primitiveList(2).sphere.type == Nz::SphereType_Ico); + } } } } diff --git a/tests/Engine/Core/SparsePtr.cpp b/tests/Engine/Core/SparsePtr.cpp index 6979549a3..e727d0807 100644 --- a/tests/Engine/Core/SparsePtr.cpp +++ b/tests/Engine/Core/SparsePtr.cpp @@ -8,7 +8,7 @@ SCENARIO("SparsePtr", "[CORE][SPARSEPTR]") GIVEN("A sparse pointer pointing to an array with a stride of 2") { std::array arrays{0, 1, 2, 3, 4}; - Nz::SparsePtr sparsePtr(arrays.begin(), 2 * sizeof(int)); + Nz::SparsePtr sparsePtr(arrays.data(), 2 * sizeof(int)); WHEN("We use operators") { diff --git a/tests/Engine/Math/Algorithm.cpp b/tests/Engine/Math/Algorithm.cpp deleted file mode 100644 index c42b90d11..000000000 --- a/tests/Engine/Math/Algorithm.cpp +++ /dev/null @@ -1,256 +0,0 @@ -#include -#include - -TEST_CASE("Approach", "[MATH][ALGORITHM]") -{ - SECTION("Approach 8 with 5 by 2") - { - REQUIRE(Nz::Approach(5, 8, 2) == 7); - } - - SECTION("Approach 5 with 8 by 2") - { - REQUIRE(Nz::Approach(8, 5, 2) == 6); - } - - SECTION("Approach 8 with 8 by 2") - { - REQUIRE(Nz::Approach(8, 8, 2) == 8); - } -} - -TEST_CASE("Clamp", "[ALGORITHM]") -{ - SECTION("Clamp 8 between 5 and 10") - { - REQUIRE(Nz::Clamp(8, 5, 10) == 8); - } - - SECTION("Clamp 4 between 5 and 10") - { - REQUIRE(Nz::Clamp(4, 5, 10) == 5); - } - - SECTION("Clamp 12 between 5 and 10") - { - REQUIRE(Nz::Clamp(12, 5, 10) == 10); - } -} - -TEST_CASE("CountBits", "[ALGORITHM]") -{ - SECTION("Number 10 has 2 bits set to 1") - { - REQUIRE(Nz::CountBits(10) == 2); - } - - SECTION("Number 0 has 0 bit set to 1") - { - REQUIRE(Nz::CountBits(0) == 0); - } -} - -TEST_CASE("DegreeToRadian", "[ALGORITHM]") -{ - SECTION("Convert 45.f degree to radian") - { - REQUIRE(Nz::DegreeToRadian(45.f) == Approx(M_PI / 4)); - } -} - -TEST_CASE("GetNearestPowerOfTwo", "[ALGORITHM]") -{ - SECTION("Nearest power of two of 0 = 1") - { - REQUIRE(Nz::GetNearestPowerOfTwo(0) == 1); - } - - SECTION("Nearest power of two of 16 = 16") - { - REQUIRE(Nz::GetNearestPowerOfTwo(16) == 16); - } - - SECTION("Nearest power of two of 17 = 32") - { - REQUIRE(Nz::GetNearestPowerOfTwo(17) == 32); - } -} - -TEST_CASE("GetNumberLength", "[ALGORITHM]") -{ - SECTION("GetNumberLength of -127 signed char") - { - signed char minus127 = -127; - REQUIRE(Nz::GetNumberLength(minus127) == 4); - } - - SECTION("GetNumberLength of 255 unsigned char") - { - unsigned char plus255 = 255; - REQUIRE(Nz::GetNumberLength(plus255) == 3); - } - - SECTION("GetNumberLength of -1270 signed int") - { - signed int minus1270 = -1270; - REQUIRE(Nz::GetNumberLength(minus1270) == 5); - } - - SECTION("GetNumberLength of 2550 unsigned int") - { - unsigned int plus2550 = 2550; - REQUIRE(Nz::GetNumberLength(plus2550) == 4); - } - - SECTION("GetNumberLength of -1270 signed long long") - { - signed long long minus12700 = -12700; - REQUIRE(Nz::GetNumberLength(minus12700) == 6); - } - - SECTION("GetNumberLength of 2550 unsigned long long") - { - unsigned long long plus25500 = 25500; - REQUIRE(Nz::GetNumberLength(plus25500) == 5); - } - - SECTION("GetNumberLength of -2.456f float") - { - float minus2P456 = -2.456f; - REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); - } - - SECTION("GetNumberLength of -2.456 double") - { - double minus2P456 = -2.456; - REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); - } - - SECTION("GetNumberLength of -2.456 long double") - { - long double minus2P456 = -2.456L; - REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); - } -} - -TEST_CASE("IntegralLog2", "[ALGORITHM]") -{ - SECTION("According to implementation, log in base 2 of 0 = 0") - { - REQUIRE(Nz::IntegralLog2(0) == 0); - } - - SECTION("Log in base 2 of 1 = 0") - { - REQUIRE(Nz::IntegralLog2(1) == 0); - } - - SECTION("Log in base 2 of 4 = 2") - { - REQUIRE(Nz::IntegralLog2(4) == 2); - } - - SECTION("Log in base 2 of 5 = 2") - { - REQUIRE(Nz::IntegralLog2(5) == 2); - } -} - -TEST_CASE("IntegralLog2Pot", "[ALGORITHM]") -{ - SECTION("According to implementation, log in base 2 of 0 = 0") - { - REQUIRE(Nz::IntegralLog2Pot(0) == 0); - } - - SECTION("Log in base 2 of 1 = 0") - { - REQUIRE(Nz::IntegralLog2Pot(1) == 0); - } - - SECTION("Log in base 2 of 4 = 2") - { - REQUIRE(Nz::IntegralLog2Pot(4) == 2); - } -} - -TEST_CASE("IntegralPow", "[ALGORITHM]") -{ - SECTION("2 to power 4") - { - REQUIRE(Nz::IntegralPow(2, 4) == 16); - } -} - -TEST_CASE("Lerp", "[ALGORITHM]") -{ - SECTION("Lerp 2 to 6 with 0.5") - { - REQUIRE(Nz::Lerp(2, 6, 0.5) == 4); - } -} - -TEST_CASE("MultiplyAdd", "[ALGORITHM]") -{ - SECTION("2 * 3 + 1") - { - REQUIRE(Nz::MultiplyAdd(2, 3, 1) == 7); - } -} - -TEST_CASE("NumberEquals", "[ALGORITHM]") -{ - SECTION("2.35 and 2.351 should be the same at 0.01") - { - CHECK(Nz::NumberEquals(2.35, 2.35, 0.01)); - } - - SECTION("3 and 4 unsigned should be the same at 1") - { - CHECK(Nz::NumberEquals(3U, 4U, 1U)); - } -} - -TEST_CASE("NumberToString", "[ALGORITHM]") -{ - SECTION("235 to string") - { - REQUIRE(Nz::NumberToString(235) == "235"); - } - - SECTION("-235 to string") - { - REQUIRE(Nz::NumberToString(-235) == "-235"); - } - - SECTION("16 in base 16 to string") - { - REQUIRE(Nz::NumberToString(16, 16) == "10"); - } -} - -TEST_CASE("RadianToDegree", "[ALGORITHM]") -{ - SECTION("PI / 4 to degree") - { - REQUIRE(Nz::RadianToDegree(M_PI / 4) == Approx(45.f)); - } -} - -TEST_CASE("StringToNumber", "[ALGORITHM]") -{ - SECTION("235 in string") - { - REQUIRE(Nz::StringToNumber("235") == 235); - } - - SECTION("-235 in string") - { - REQUIRE(Nz::StringToNumber("-235") == -235); - } - - SECTION("16 in base 16 in string") - { - REQUIRE(Nz::StringToNumber("10", 16) == 16); - } -} From f9a95ce054f4ada8da615d53795326aca935602d Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 13:59:17 +0100 Subject: [PATCH 137/229] Core: Made Mutex and ConditionVariable moveable Former-commit-id: 891fbb35d050f3df572cbbecd0191b75f556e59d --- include/Nazara/Core/ConditionVariable.hpp | 6 ++++-- include/Nazara/Core/ConditionVariable.inl | 25 +++++++++++++++++++++++ include/Nazara/Core/Mutex.hpp | 6 ++++-- include/Nazara/Core/Mutex.inl | 25 +++++++++++++++++++++++ src/Nazara/Core/ConditionVariable.cpp | 14 +++++++++++++ src/Nazara/Core/Mutex.cpp | 18 ++++++++++++++++ 6 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 include/Nazara/Core/ConditionVariable.inl create mode 100644 include/Nazara/Core/Mutex.inl diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index 4096e00b4..f6aeafe9b 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -19,7 +19,7 @@ namespace Nz public: ConditionVariable(); ConditionVariable(const ConditionVariable&) = delete; - ConditionVariable(ConditionVariable&&) = delete; ///TODO + inline ConditionVariable(ConditionVariable&& condition) noexcept; ~ConditionVariable(); void Signal(); @@ -29,11 +29,13 @@ namespace Nz bool Wait(Mutex* mutex, UInt32 timeout); ConditionVariable& operator=(const ConditionVariable&) = delete; - ConditionVariable& operator=(ConditionVariable&&) = delete; ///TODO + inline ConditionVariable& operator=(ConditionVariable&& condition) noexcept; private: ConditionVariableImpl* m_impl; }; } +#include + #endif // NAZARA_CONDITIONVARIABLE_HPP diff --git a/include/Nazara/Core/ConditionVariable.inl b/include/Nazara/Core/ConditionVariable.inl new file mode 100644 index 000000000..636c98493 --- /dev/null +++ b/include/Nazara/Core/ConditionVariable.inl @@ -0,0 +1,25 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + /*! + * \class Nz::ConditionVariable + */ + + /*! + * \brief Constructs a ConditionVariable object by moving another one + */ + inline ConditionVariable::ConditionVariable(ConditionVariable&& condition) noexcept : + m_impl(condition.m_impl) + { + condition.m_impl = nullptr; + } +} + +#include diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index e49de7512..14de9d282 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -20,7 +20,7 @@ namespace Nz public: Mutex(); Mutex(const Mutex&) = delete; - Mutex(Mutex&&) = delete; ///TODO + inline Mutex(Mutex&& mutex) noexcept; ~Mutex(); void Lock(); @@ -28,11 +28,13 @@ namespace Nz void Unlock(); Mutex& operator=(const Mutex&) = delete; - Mutex& operator=(Mutex&&) = delete; ///TODO + Mutex& operator=(Mutex&& mutex) noexcept; private: MutexImpl* m_impl; }; } +#include + #endif // NAZARA_MUTEX_HPP diff --git a/include/Nazara/Core/Mutex.inl b/include/Nazara/Core/Mutex.inl new file mode 100644 index 000000000..7d0618071 --- /dev/null +++ b/include/Nazara/Core/Mutex.inl @@ -0,0 +1,25 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + /*! + * \class Nz::Mutex + */ + + /*! + * \brief Constructs a Mutex object by moving another one + */ + inline Mutex::Mutex(Mutex&& mutex) noexcept : + m_impl(mutex.m_impl) + { + mutex.m_impl = nullptr; + } +} + +#include diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index c660c6464..c01b47722 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -101,4 +101,18 @@ namespace Nz NazaraAssert(mutex != nullptr, "Mutex must be valid"); return m_impl->Wait(mutex->m_impl, timeout); } + + /*! + * \brief Moves a condition to another ConditionVariable object + * \return A reference to the object + */ + ConditionVariable& ConditionVariable::operator=(ConditionVariable&& condition) noexcept + { + delete m_impl; + + m_impl = condition.m_impl; + condition.m_impl = nullptr; + + return *this; + } } diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index 647fffc12..2d17276f1 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #if defined(NAZARA_PLATFORM_WINDOWS) #include @@ -49,6 +50,7 @@ namespace Nz void Mutex::Lock() { + NazaraAssert(m_impl, "Cannot lock a moved mutex"); m_impl->Lock(); } @@ -59,6 +61,7 @@ namespace Nz bool Mutex::TryLock() { + NazaraAssert(m_impl, "Cannot lock a moved mutex"); return m_impl->TryLock(); } @@ -70,6 +73,21 @@ namespace Nz void Mutex::Unlock() { + NazaraAssert(m_impl, "Cannot unlock a moved mutex"); m_impl->Unlock(); } + + /*! + * \brief Moves a mutex to another mutex object + * \return A reference to the object + */ + Mutex& Mutex::operator=(Mutex&& mutex) noexcept + { + delete m_impl; + + m_impl = mutex.m_impl; + mutex.m_impl = nullptr; + + return *this; + } } From 188c1e4c1e3e18138fa39380e1ba1fe1c36ebd70 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 13:59:31 +0100 Subject: [PATCH 138/229] Core/Bitset: Made destructor and Clear() noexcept Former-commit-id: 0d09070fcb5d17812eb938c9873213107bd97f7c --- include/Nazara/Core/Bitset.hpp | 4 ++-- include/Nazara/Core/Bitset.inl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index 9c45b3689..630d14a40 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -32,9 +32,9 @@ namespace Nz Bitset(const Bitset& bitset) = default; explicit Bitset(const String& bits); Bitset(Bitset&& bitset) noexcept = default; - ~Bitset() = default; + ~Bitset() noexcept = default; - void Clear(); + void Clear() noexcept; unsigned int Count() const; void Flip(); diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 1b4cab200..330d174bc 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -114,7 +114,7 @@ namespace Nz */ template - void Bitset::Clear() + void Bitset::Clear() noexcept { m_bitCount = 0; m_blocks.clear(); From cc7263e398c9652bd049c1fc02fa8a649e619499 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 13:59:41 +0100 Subject: [PATCH 139/229] Core/MemoryPool: Fix missing include Former-commit-id: fd993b3117c61e0fe6e9e34b0e24f2bf84b3186e --- include/Nazara/Core/MemoryPool.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 1f3993974..bd5bc8882 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -4,6 +4,7 @@ #include #include +#include #include namespace Nz From c93f1c0d738d3e72d745a8c68d3659e4f58a01d9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 14:00:10 +0100 Subject: [PATCH 140/229] Update Doxyfile Former-commit-id: 8aa20e940c338b2844811d9beae055846b8bd33f --- Doxyfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doxyfile b/Doxyfile index 6ab581011..7ac8e5f8c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -319,7 +319,7 @@ AUTOLINK_SUPPORT = YES # diagrams that involve STL classes more complete and accurate. # The default value is: NO. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. @@ -412,7 +412,7 @@ TYPEDEF_HIDES_STRUCT = NO # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. -LOOKUP_CACHE_SIZE = 0 +LOOKUP_CACHE_SIZE = 5 #--------------------------------------------------------------------------- # Build related configuration options From 40e12ebffac0a96c8697410e2ae6a77c8a34ef5e Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 14:00:27 +0100 Subject: [PATCH 141/229] Network/Enum: Fix typo Former-commit-id: 8a41d1a2a915a8c5565e3a9ecc93898a35ed2133 --- include/Nazara/Network/Enums.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 6fbb5aff3..3d077519a 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -52,7 +52,7 @@ namespace Nz SocketError_Packet, //< The packet encoding/decoding failed, probably because of corrupted data SocketError_NetworkError, //< The network system has failed (maybe network is down) SocketError_NotInitialized, //< Nazara network has not been initialized - SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adaptater) + SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adapter) SocketError_ResolveError, //< The hostname couldn't be resolved (more information in ResolveError code) SocketError_ResourceError, //< The operating system lacks the resources to proceed (e.g. memory/socket descriptor) SocketError_TimedOut, //< The operation timed out From 36067e31c49576c21b35207469d0fae8dfd69bfa Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 14:00:53 +0100 Subject: [PATCH 142/229] Utility/Window: Make Window moveable Former-commit-id: 8c780562acc61d15437ed21c16eed92b6dd97373 --- include/Nazara/Utility/Window.hpp | 22 +++-- include/Nazara/Utility/Window.inl | 154 ++++++++++++++++++++++++++++++ src/Nazara/Utility/Window.cpp | 95 ------------------ 3 files changed, 166 insertions(+), 105 deletions(-) create mode 100644 include/Nazara/Utility/Window.inl diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index 75f066bd8..af23be7f1 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -38,14 +38,14 @@ namespace Nz friend class Utility; public: - Window(); - Window(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default); - Window(WindowHandle handle); + inline Window(); + inline Window(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default); + inline Window(WindowHandle handle); Window(const Window&) = delete; - Window(Window&&) = delete; ///TODO + inline Window(Window&& window) noexcept; virtual ~Window(); - void Close(); + inline void Close(); bool Create(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default); bool Create(WindowHandle handle); @@ -66,9 +66,9 @@ namespace Nz bool HasFocus() const; bool IsMinimized() const; - bool IsOpen(bool checkClosed = true); - bool IsOpen() const; - bool IsValid() const; + inline bool IsOpen(bool checkClosed = true); + inline bool IsOpen() const; + inline bool IsValid() const; bool IsVisible() const; bool PollEvent(WindowEvent* event); @@ -93,7 +93,7 @@ namespace Nz bool WaitEvent(WindowEvent* event); Window& operator=(const Window&) = delete; - Window& operator=(Window&&) = delete; ///TODO + inline Window& operator=(Window&& window); protected: virtual bool OnWindowCreated(); @@ -104,7 +104,7 @@ namespace Nz private: void IgnoreNextMouseEvent(int mouseX, int mouseY) const; - void PushEvent(const WindowEvent& event); + inline void PushEvent(const WindowEvent& event); static bool Initialize(); static void Uninitialize(); @@ -122,4 +122,6 @@ namespace Nz }; } +#include + #endif // NAZARA_WINDOW_HPP diff --git a/include/Nazara/Utility/Window.inl b/include/Nazara/Utility/Window.inl new file mode 100644 index 000000000..ebf5dfbee --- /dev/null +++ b/include/Nazara/Utility/Window.inl @@ -0,0 +1,154 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + /*! + * \class Nz::Window + */ + + inline Window::Window() : + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl(nullptr), + m_eventListener(true), + m_waitForEvent(false) + #else + m_impl(nullptr) + #endif + { + } + + inline Window::Window(VideoMode mode, const String& title, UInt32 style) : + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl(nullptr), + m_eventListener(true), + m_waitForEvent(false) + #else + m_impl(nullptr) + #endif + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(mode, title, style); + } + + inline Window::Window(WindowHandle handle) : + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl(nullptr), + m_eventListener(true), + m_waitForEvent(false) + #else + m_impl(nullptr) + #endif + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(handle); + } + + /*! + * \brief Constructs a Window object by moving another one + */ + inline Window::Window(Window&& window) noexcept : + m_impl(window.m_impl), + m_events(std::move(window.m_events)), + #if NAZARA_UTILITY_THREADED_WINDOW + m_eventCondition(std::move(window.m_eventCondition)), + m_eventMutex(std::move(window.m_eventMutex)), + m_eventConditionMutex(std::move(window.m_eventConditionMutex)), + m_eventListener(window.m_eventListener), + m_waitForEvent(window.m_waitForEvent), + #endif + m_closed(window.m_closed), + m_ownsWindow(window.m_ownsWindow) + { + window.m_impl = nullptr; + } + + inline Window::~Window() + { + Destroy(); + } + + inline void Window::Close() + { + m_closed = true; // The window will be closed at the next non-const IsOpen() call + } + + inline bool Window::IsOpen(bool checkClosed) + { + if (!m_impl) + return false; + + if (checkClosed && m_closed) + { + Destroy(); + return false; + } + + return true; + } + + inline bool Window::IsOpen() const + { + return m_impl != nullptr; + } + + inline bool Window::IsValid() const + { + return m_impl != nullptr; + } + + inline void Window::PushEvent(const WindowEvent& event) + { + #if NAZARA_UTILITY_THREADED_WINDOW + m_eventMutex.Lock(); + #endif + + m_events.push(event); + if (event.type == WindowEventType_Resized) + OnWindowResized(); + + #if NAZARA_UTILITY_THREADED_WINDOW + m_eventMutex.Unlock(); + + if (m_waitForEvent) + { + m_eventConditionMutex.Lock(); + m_eventCondition.Signal(); + m_eventConditionMutex.Unlock(); + } + #endif + } + + /*! + * \brief Moves a window to another window object + * \return A reference to the object + */ + inline Window& Window::operator=(Window&& window) + { + Destroy(); + + m_closed = window.m_closed; + m_impl = window.m_impl; + m_events = std::move(window.m_events); + m_ownsWindow = window.m_ownsWindow; + + window.m_impl = nullptr; + + #if NAZARA_UTILITY_THREADED_WINDOW + m_eventCondition = std::move(window.m_eventCondition); + m_eventMutex = std::move(window.m_eventMutex); + m_eventConditionMutex = std::move(window.m_eventConditionMutex); + m_eventListener = window.m_eventListener; + m_waitForEvent = window.m_waitForEvent; + #endif + + return *this; + } +} + +#include diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index fec1615af..e246144d2 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -28,53 +28,6 @@ namespace Nz Window* fullscreenWindow = nullptr; } - Window::Window() : - #if NAZARA_UTILITY_THREADED_WINDOW - m_impl(nullptr), - m_eventListener(true), - m_waitForEvent(false) - #else - m_impl(nullptr) - #endif - { - } - - Window::Window(VideoMode mode, const String& title, UInt32 style) : - #if NAZARA_UTILITY_THREADED_WINDOW - m_impl(nullptr), - m_eventListener(true), - m_waitForEvent(false) - #else - m_impl(nullptr) - #endif - { - ErrorFlags flags(ErrorFlag_ThrowException, true); - Create(mode, title, style); - } - - Window::Window(WindowHandle handle) : - #if NAZARA_UTILITY_THREADED_WINDOW - m_impl(nullptr), - m_eventListener(true), - m_waitForEvent(false) - #else - m_impl(nullptr) - #endif - { - ErrorFlags flags(ErrorFlag_ThrowException, true); - Create(handle); - } - - Window::~Window() - { - Destroy(); - } - - void Window::Close() - { - m_closed = true; // On retarde la fermeture jusqu'au prochain IsOpen - } - bool Window::Create(VideoMode mode, const String& title, UInt32 style) { // Si la fenêtre est déjà ouverte, nous conservons sa position @@ -317,27 +270,6 @@ namespace Nz return m_impl->HasFocus(); } - bool Window::IsOpen(bool checkClosed) - { - if (m_impl) - { - if (m_closed && checkClosed) - { - Destroy(); - return false; - } - else - return true; - } - else - return false; - } - - bool Window::IsOpen() const - { - return m_impl != nullptr; - } - bool Window::IsMinimized() const { #if NAZARA_UTILITY_SAFE @@ -351,11 +283,6 @@ namespace Nz return m_impl->IsMinimized(); } - bool Window::IsValid() const - { - return m_impl != nullptr; - } - bool Window::IsVisible() const { #if NAZARA_UTILITY_SAFE @@ -710,28 +637,6 @@ namespace Nz m_impl->IgnoreNextMouseEvent(mouseX, mouseY); } - void Window::PushEvent(const WindowEvent& event) - { - #if NAZARA_UTILITY_THREADED_WINDOW - m_eventMutex.Lock(); - #endif - - m_events.push(event); - if (event.type == WindowEventType_Resized) - OnWindowResized(); - - #if NAZARA_UTILITY_THREADED_WINDOW - m_eventMutex.Unlock(); - - if (m_waitForEvent) - { - m_eventConditionMutex.Lock(); - m_eventCondition.Signal(); - m_eventConditionMutex.Unlock(); - } - #endif - } - bool Window::Initialize() { return WindowImpl::Initialize(); From dbce7592a93cde18c49436dc0ebff213e137d2d7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 14:01:31 +0100 Subject: [PATCH 143/229] Sdk: Make World moveable Former-commit-id: 285cb9da4cbafd3da0c0859eb9d366bb2fb978a3 --- SDK/include/NDK/BaseSystem.hpp | 2 +- SDK/include/NDK/BaseSystem.inl | 6 +++--- SDK/include/NDK/Entity.hpp | 5 ++++- SDK/include/NDK/Entity.inl | 7 +++++++ SDK/include/NDK/World.hpp | 8 ++++---- SDK/include/NDK/World.inl | 25 ++++++++++++++++++++++++- SDK/src/NDK/Entity.cpp | 4 ++-- SDK/src/NDK/World.cpp | 4 ++-- 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 0cb66b3b4..9a81c83e0 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -71,7 +71,7 @@ namespace Ndk inline void RemoveEntity(Entity* entity); - inline void SetWorld(World& world); + inline void SetWorld(World* world) noexcept; inline void ValidateEntity(Entity* entity, bool justAdded); diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index da1f04d15..0c86ddfdd 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -172,9 +172,9 @@ namespace Ndk OnEntityValidation(entity, justAdded); } - inline void BaseSystem::SetWorld(World& world) + inline void BaseSystem::SetWorld(World* world) noexcept { - m_world = &world; + m_world = world; } inline bool BaseSystem::Initialize() @@ -186,6 +186,6 @@ namespace Ndk inline void BaseSystem::Uninitialize() { - // Rien à faire + // Nothing to do } } diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index c7ab78bf5..71f5a4fc7 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -60,13 +60,16 @@ namespace Ndk Entity& operator=(Entity&&) = delete; private: - Entity(World& world, EntityId id); + Entity(World* world, EntityId id); void Create(); void Destroy(); inline void RegisterHandle(EntityHandle* handle); inline void RegisterSystem(SystemIndex index); + + inline void SetWorld(World* world) noexcept; + inline void UnregisterHandle(EntityHandle* handle); inline void UnregisterSystem(SystemIndex index); diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index f185a4b0d..caca8b766 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -113,6 +113,13 @@ namespace Ndk m_systemBits.UnboundedSet(index); } + inline void Entity::SetWorld(World* world) noexcept + { + NazaraAssert(world, "An entity must be attached to a world at any time"); + + m_world = world; + } + inline void Entity::UnregisterHandle(EntityHandle* handle) { ///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index 3b7e16684..ff1de0ef7 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -27,8 +27,8 @@ namespace Ndk inline World(bool addDefaultSystems = true); World(const World&) = delete; - World(World&&) = delete; ///TODO - ~World(); + inline World(World&& world) noexcept; + ~World() noexcept; void AddDefaultSystems(); @@ -38,7 +38,7 @@ namespace Ndk const EntityHandle& CreateEntity(); inline EntityList CreateEntities(unsigned int count); - void Clear(); + void Clear() noexcept; const EntityHandle& GetEntity(EntityId id); inline const EntityList& GetEntities(); @@ -62,7 +62,7 @@ namespace Ndk inline void Update(float elapsedTime); World& operator=(const World&) = delete; - World& operator=(World&&) = delete; ///TODO + inline World& operator=(World&& world) noexcept; private: inline void Invalidate(); diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index a9e22774b..64212357a 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -13,6 +13,11 @@ namespace Ndk AddDefaultSystems(); } + inline World::World(World&& world) noexcept + { + operator=(std::move(world)); + } + inline BaseSystem& World::AddSystem(std::unique_ptr&& system) { NazaraAssert(system, "System must be valid"); @@ -25,7 +30,7 @@ namespace Ndk // Affectation et retour du système m_systems[index] = std::move(system); - m_systems[index]->SetWorld(*this); + m_systems[index]->SetWorld(this); Invalidate(); // On force une mise à jour de toutes les entités @@ -152,4 +157,22 @@ namespace Ndk { m_dirtyEntities.UnboundedSet(id, true); } + + inline World& World::operator=(World&& world) noexcept + { + m_aliveEntities = std::move(world.m_aliveEntities); + m_dirtyEntities = std::move(world.m_dirtyEntities); + m_freeIdList = std::move(world.m_freeIdList); + m_killedEntities = std::move(world.m_killedEntities); + + m_entities = std::move(world.m_entities); + for (EntityBlock& block : m_entities) + block.entity.SetWorld(this); + + m_systems = std::move(world.m_systems); + for (const auto& systemPtr : m_systems) + systemPtr->SetWorld(this); + + return *this; + } } diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index a2e69d2e1..afd3aa1b6 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -23,9 +23,9 @@ namespace Ndk handle->OnEntityMoved(this); } - Entity::Entity(World& world, EntityId id) : + Entity::Entity(World* world, EntityId id) : m_id(id), - m_world(&world) + m_world(world) { } diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index e8fff42f2..483af6d27 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -46,7 +46,7 @@ namespace Ndk id = m_entities.size(); // Impossible d'utiliser emplace_back à cause de la portée - m_entities.push_back(Entity(*this, id)); + m_entities.push_back(Entity(this, id)); } // On initialise l'entité et on l'ajoute à la liste des entités vivantes @@ -59,7 +59,7 @@ namespace Ndk return m_aliveEntities.back(); } - void World::Clear() + void World::Clear() noexcept { ///DOC: Tous les handles sont correctement invalidés From 1c4135fc09a926f9f682b56ea558260242198465 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 15:37:05 +0100 Subject: [PATCH 144/229] Improve documentation Former-commit-id: 08d70f6a53a7f12d2748d145d1fe139595a1b39e --- include/Nazara/Core/AbstractLogger.docx | 1 + include/Nazara/Core/Algorithm.inl | 33 ++++++++++++++----------- include/Nazara/Core/Bitset.inl | 15 +++++------ include/Nazara/Core/CallOnExit.inl | 1 + include/Nazara/Core/Color.inl | 1 + include/Nazara/Core/Config.hpp | 5 ++++ include/Nazara/Core/Endianness.inl | 2 ++ include/Nazara/Core/Functor.inl | 27 ++++++++++++-------- include/Nazara/Core/Initializer.inl | 9 ++----- include/Nazara/Core/MemoryHelper.inl | 4 +-- include/Nazara/Core/MemoryPool.inl | 1 + include/Nazara/Core/MemoryStream.inl | 6 ++--- include/Nazara/Core/Mutex.inl | 1 + include/Nazara/Core/ObjectLibrary.inl | 8 ++---- include/Nazara/Core/ObjectRef.inl | 23 +++-------------- include/Nazara/Core/Primitive.inl | 27 +------------------- include/Nazara/Core/ResourceLoader.inl | 9 ++----- include/Nazara/Core/ResourceManager.inl | 12 ++------- include/Nazara/Core/Signal.inl | 17 +++++++------ include/Nazara/Core/SparsePtr.inl | 13 +++++----- include/Nazara/Core/Stream.inl | 1 + include/Nazara/Core/String.inl | 1 + include/Nazara/Core/TaskScheduler.inl | 1 + include/Nazara/Core/Thread.inl | 7 +++--- include/Nazara/Math/Algorithm.inl | 29 ++++++++++++++++++++++ include/Nazara/Math/BoundingVolume.inl | 19 +++++++------- include/Nazara/Math/Box.inl | 17 +++++++------ include/Nazara/Math/Config.hpp | 5 ++++ include/Nazara/Math/EulerAngles.inl | 11 +++++---- include/Nazara/Math/Frustum.inl | 5 ++-- include/Nazara/Math/Matrix4.inl | 11 +++++---- include/Nazara/Math/OrientedBox.inl | 13 +++++----- include/Nazara/Math/Plane.inl | 15 +++++------ include/Nazara/Math/Quaternion.inl | 13 +++++----- include/Nazara/Math/Ray.inl | 15 +++++------ include/Nazara/Math/Rect.inl | 17 +++++++------ include/Nazara/Math/Sphere.inl | 11 +++++---- include/Nazara/Math/Vector2.inl | 17 +++++++------ include/Nazara/Math/Vector3.inl | 19 +++++++------- include/Nazara/Math/Vector4.inl | 23 ++++++++--------- src/Nazara/Core/AbstractHash.cpp | 3 ++- src/Nazara/Core/AbstractLogger.cpp | 3 ++- src/Nazara/Core/ByteArray.cpp | 1 + src/Nazara/Core/ByteStream.cpp | 1 + src/Nazara/Core/Clock.cpp | 9 +------ src/Nazara/Core/ConditionVariable.cpp | 1 + src/Nazara/Core/Core.cpp | 3 ++- src/Nazara/Core/Directory.cpp | 1 + src/Nazara/Core/DynLib.cpp | 1 + src/Nazara/Core/Error.cpp | 1 + src/Nazara/Core/ErrorFlags.cpp | 1 + src/Nazara/Core/File.cpp | 1 + src/Nazara/Core/FileLogger.cpp | 1 + src/Nazara/Core/GuillotineBinPack.cpp | 1 + src/Nazara/Core/HardwareInfo.cpp | 1 + src/Nazara/Core/LockGuard.cpp | 1 + src/Nazara/Core/Log.cpp | 1 + src/Nazara/Core/MemoryManager.cpp | 1 + src/Nazara/Core/MemoryStream.cpp | 1 + src/Nazara/Core/MemoryView.cpp | 3 ++- src/Nazara/Core/Mutex.cpp | 1 + src/Nazara/Core/ParameterList.cpp | 1 + src/Nazara/Core/PluginManager.cpp | 1 + src/Nazara/Core/PrimitiveList.cpp | 1 + src/Nazara/Core/RefCounted.cpp | 1 + src/Nazara/Core/Resource.cpp | 1 + src/Nazara/Core/Semaphore.cpp | 1 + src/Nazara/Core/StdLogger.cpp | 1 + src/Nazara/Core/Stream.cpp | 1 + src/Nazara/Core/String.cpp | 1 + src/Nazara/Core/StringStream.cpp | 1 + src/Nazara/Core/TaskScheduler.cpp | 3 ++- src/Nazara/Core/Thread.cpp | 3 ++- src/Nazara/Core/Unicode.cpp | 1 + 74 files changed, 277 insertions(+), 242 deletions(-) diff --git a/include/Nazara/Core/AbstractLogger.docx b/include/Nazara/Core/AbstractLogger.docx index cdc37f3f8..6ac06b95c 100644 --- a/include/Nazara/Core/AbstractLogger.docx +++ b/include/Nazara/Core/AbstractLogger.docx @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp /*! +* \ingroup core * \class Nz::AbstractLogger * \brief Logger interface */ diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index a9855c62c..c45147d79 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -31,7 +31,8 @@ namespace Nz } /*! - * \brief Applies the tuple to the function + * \ingroup core + * \brief Applies the tuple to the function (e.g. calls the function using the tuple content as arguments) * \return The result of the function * * \param fn Function @@ -39,7 +40,6 @@ namespace Nz * * \see Apply */ - template auto Apply(F&& fn, Tuple&& t) { @@ -49,7 +49,8 @@ namespace Nz } /*! - * \brief Applies the tuple to the member function on an object + * \ingroup core + * \brief Applies the tuple to the member function on an object (e.g. calls the member function using the tuple content as arguments) * \return The result of the member function called * * \param object Object of a class @@ -58,7 +59,6 @@ namespace Nz * * \see Apply */ - template auto Apply(O& object, F&& fn, Tuple&& t) { @@ -68,15 +68,17 @@ namespace Nz } /*! + * \ingroup core * \brief Computes the hash of a hashable object * \return A bytearray which represents the hash * * \param hash Enumeration of type HashType - * \param v Object to hash, must be convertible to "Nz::String" + * \param v Object to hash * + * \remark a HashAppend specialization for type T is required + * * \see ComputeHash */ - template ByteArray ComputeHash(HashType hash, const T& v) { @@ -84,17 +86,18 @@ namespace Nz } /*! + * \ingroup core * \brief Computes the hash of a hashable object * \return A bytearray which represents the hash * * \param hash Pointer to abstract hash - * \param v Object to hash, must be convertible to "Nz::String" + * \param v Object to hash * * \remark Produce a NazaraAssert if pointer to Abstracthash is invalid + * \remark a HashAppend specialization for type T is required * * \see ComputeHash */ - template ByteArray ComputeHash(AbstractHash* hash, const T& v) { @@ -108,6 +111,7 @@ namespace Nz } /*! + * \ingroup core * \brief Returns the number of elements in a C-array * \return The number of elements * @@ -115,7 +119,6 @@ namespace Nz * * \see CountOf */ - template constexpr std::size_t CountOf(T(&name)[N]) noexcept { @@ -123,6 +126,7 @@ namespace Nz } /*! + * \ingroup core * \brief Returns the number of elements in a container * \return The number of elements * @@ -130,7 +134,6 @@ namespace Nz * * \see CountOf */ - template std::size_t CountOf(const T& c) { @@ -138,12 +141,12 @@ namespace Nz } /*! + * \ingroup core * \brief Combines two hash in one * * \param seed First value that will be modified (expected to be 64bits) * \param v Second value to hash */ - // Algorithm from CityHash by Google // http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co template @@ -167,6 +170,7 @@ namespace Nz template struct PointedType {typedef T type;}; /*! + * \ingroup core * \brief Serializes a boolean * \return true if serialization succedeed * @@ -175,7 +179,6 @@ namespace Nz * * \see Serialize, Unserialize */ - inline bool Serialize(SerializationContext& context, bool value) { if (context.currentBitPos == 8) @@ -194,6 +197,7 @@ namespace Nz } /*! + * \ingroup core * \brief Serializes an arithmetic type * \return true if serialization succedeed * @@ -202,7 +206,6 @@ namespace Nz * * \see Serialize, Unserialize */ - template std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { @@ -222,6 +225,7 @@ namespace Nz } /*! + * \ingroup core * \brief Unserializes a boolean * \return true if unserialization succedeed * @@ -230,7 +234,6 @@ namespace Nz * * \see Serialize, Unserialize */ - inline bool Unserialize(SerializationContext& context, bool* value) { if (context.currentBitPos == 8) @@ -250,6 +253,7 @@ namespace Nz } /*! + * \ingroup core * \brief Unserializes an arithmetic type * \return true if unserialization succedeed * @@ -260,7 +264,6 @@ namespace Nz * * \see Serialize, Unserialize */ - template std::enable_if_t::value, bool> Unserialize(SerializationContext& context, T* value) { diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 330d174bc..70c1158eb 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -17,14 +17,15 @@ namespace Nz { /*! - * \class Nz::Bitset + * \ingroup core + * \class Nz::Bitset * \brief Core class that represents a set of bits * * This class meets the requirements of Container, AllocatorAwareContainer, SequenceContainer */ /*! - * \brief Constructs a Bitset object by default + * \brief Constructs a Bitset object by default */ template @@ -34,7 +35,7 @@ namespace Nz } /*! - * \brief Constructs a Bitset object of bitCount bits to value val + * \brief Constructs a Bitset object of bitCount bits to value val * * \param bitCount Number of bits * \param val Value of those bits, by default false @@ -48,7 +49,7 @@ namespace Nz } /*! - * \brief Constructs a Bitset object from the contents initialized with a copy of the null-terminated character string pointed to by bits + * \brief Constructs a Bitset object from the contents initialized with a copy of the null-terminated character string pointed to by bits * * \param bits Null-terminated character string containing only '0' and '1' * @@ -62,7 +63,7 @@ namespace Nz } /*! - * \brief Constructs a Bitset object from the contents initialized with a copy of the character string pointed to by bits takings the bitCount first characters + * \brief Constructs a Bitset object from the contents initialized with a copy of the character string pointed to by bits takings the bitCount first characters * * \param bits Character string containing only '0' and '1' * \param bitCount Number of characters to take into consideration @@ -96,7 +97,7 @@ namespace Nz } /*! - * \brief Constructs a Bitset object from a Nz::String + * \brief Constructs a Bitset object from a Nz::String * * \param bits String containing only '0' and '1' */ @@ -912,7 +913,7 @@ namespace Nz template template - void* Bitset::Bit::operator&() const + void* Bitset::Bit::operator&() const { // The template is necessary to make it fail only when used static_assert(!BadCall, "It is impossible to take the address of a bit in a bitset"); diff --git a/include/Nazara/Core/CallOnExit.inl b/include/Nazara/Core/CallOnExit.inl index 987da852e..0318752cc 100644 --- a/include/Nazara/Core/CallOnExit.inl +++ b/include/Nazara/Core/CallOnExit.inl @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::CallOnExit * \brief Core class that represents a function to call at the end of the scope */ diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 7dcfc7d75..c3359cd0f 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -12,6 +12,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Color * \brief Core class that represents a color */ diff --git a/include/Nazara/Core/Config.hpp b/include/Nazara/Core/Config.hpp index bd67daec6..955b98c75 100644 --- a/include/Nazara/Core/Config.hpp +++ b/include/Nazara/Core/Config.hpp @@ -27,6 +27,11 @@ #ifndef NAZARA_CONFIG_CORE_HPP #define NAZARA_CONFIG_CORE_HPP +/*! +* \defgroup core (NazaraCore) Core module +* Core/System module including classes to handle threading, time, hardware info, memory management, etc... +*/ + /// Each modification of a parameter needs a recompilation of the module // Precision of reals when transformed into string (Max. numbers after the coma) diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index 72cb9fc43..400224920 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \brief Gets the platform endianness * \return Type of the endianness */ @@ -22,6 +23,7 @@ namespace Nz } /*! + * \ingroup core * \brief Swaps the byte for endianness operations * * \param buffer Raw memory diff --git a/include/Nazara/Core/Functor.inl b/include/Nazara/Core/Functor.inl index 96c22b175..d5cefe434 100644 --- a/include/Nazara/Core/Functor.inl +++ b/include/Nazara/Core/Functor.inl @@ -7,8 +7,9 @@ namespace Nz { /*! - * \class Nz::StdLogger - * \brief Core class that represents a functor + * \ingroup core + * \class Nz::FunctorWithoutArgs + * \brief Core class that represents a functor using a function without argument */ /*! @@ -16,7 +17,6 @@ namespace Nz * * \param func Function to execute */ - template FunctorWithoutArgs::FunctorWithoutArgs(F func) : m_func(func) @@ -26,7 +26,6 @@ namespace Nz /*! * \brief Runs the function */ - template void FunctorWithoutArgs::Run() { @@ -34,12 +33,17 @@ namespace Nz } /*! - * \brief Constructs a FunctorWithoutArgs object with a function and its arguments + * \ingroup core + * \class Nz::FunctorWithArgs + * \brief Core class that represents a functor using a function with arguments + */ + + /*! + * \brief Constructs a FunctorWithArgs object with a function and its arguments * * \param func Function to execute * \param args Arguments for the function */ - template FunctorWithArgs::FunctorWithArgs(F func, Args&&... args) : m_func(func), @@ -50,7 +54,6 @@ namespace Nz /*! * \brief Runs the function */ - template void FunctorWithArgs::Run() { @@ -58,12 +61,17 @@ namespace Nz } /*! - * \brief Constructs a FunctorWithoutArgs object with a member function and an object + * \ingroup core + * \class Nz::MemberWithoutArgs + * \brief Core class that represents a functor using a member function + */ + + /*! + * \brief Constructs a MemberWithoutArgs object with a member function and an object * * \param func Member function to execute * \param object Object to execute on */ - template MemberWithoutArgs::MemberWithoutArgs(void (C::*func)(), C* object) : m_func(func), @@ -74,7 +82,6 @@ namespace Nz /*! * \brief Runs the function */ - template void MemberWithoutArgs::Run() { diff --git a/include/Nazara/Core/Initializer.inl b/include/Nazara/Core/Initializer.inl index cbf613699..23cc7b2de 100644 --- a/include/Nazara/Core/Initializer.inl +++ b/include/Nazara/Core/Initializer.inl @@ -48,7 +48,8 @@ namespace Nz } /*! - * \class Nz::Initializer + * \ingroup core + * \class Nz::Initializer * \brief Core class that represents a module initializer */ @@ -57,7 +58,6 @@ namespace Nz * * \param initialize Initialize the module */ - template Initializer::Initializer(bool initialize) : m_initialized(false) @@ -71,7 +71,6 @@ namespace Nz * * \see Uninitialize */ - template Initializer::~Initializer() { @@ -83,7 +82,6 @@ namespace Nz * * \see Uninitialize */ - template bool Initializer::Initialize() { @@ -97,7 +95,6 @@ namespace Nz * \brief Checks whether the module is initialized * \return true if initialized */ - template bool Initializer::IsInitialized() const { @@ -109,7 +106,6 @@ namespace Nz * * \see Initialize */ - template void Initializer::Uninitialize() { @@ -121,7 +117,6 @@ namespace Nz * \brief Converts the initializer to boolean * \return true if initialized */ - template Initializer::operator bool() const { diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index 507f57bab..7f77dd041 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -17,6 +17,7 @@ namespace Nz { /*! + * \ingroup core * \fn Nz::MemoryHelper * \brief Core functions that helps the handle of memory in the engine */ @@ -26,7 +27,6 @@ namespace Nz * * \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator delete */ - inline void OperatorDelete(void* ptr) { #if NAZARA_CORE_MANAGE_MEMORY @@ -41,7 +41,6 @@ namespace Nz * * \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator new */ - inline void* OperatorNew(std::size_t size) { #if NAZARA_CORE_MANAGE_MEMORY @@ -58,7 +57,6 @@ namespace Nz * \param ptr Pointer to raw memory allocated * \param args Arguments for the constructor */ - template T* PlacementNew(void* ptr, Args&&... args) { diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index bd5bc8882..14c3868dd 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -10,6 +10,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::MemoryPool * \brief Core class that represents a memory pool */ diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl index 839f2564c..79a19f467 100644 --- a/include/Nazara/Core/MemoryStream.inl +++ b/include/Nazara/Core/MemoryStream.inl @@ -8,9 +8,10 @@ namespace Nz { /*! + * \ingroup core + * \class Nz::MemoryStream * \brief Constructs a MemoryStream object by default */ - inline MemoryStream::MemoryStream() : Stream(StreamOption_None, OpenMode_ReadWrite), m_pos(0) @@ -23,7 +24,6 @@ namespace Nz * \param byteArray Bytes to stream * \param openMode Reading/writing mode for the stream */ - inline MemoryStream::MemoryStream(ByteArray* byteArray, UInt32 openMode) : MemoryStream() { @@ -36,7 +36,6 @@ namespace Nz * * \remark Produces a NazaraAssert if buffer is invalid */ - inline ByteArray& MemoryStream::GetBuffer() { NazaraAssert(m_buffer, "Invalid buffer"); @@ -50,7 +49,6 @@ namespace Nz * * \remark Produces a NazaraAssert if buffer is invalid */ - inline const ByteArray& MemoryStream::GetBuffer() const { NazaraAssert(m_buffer, "Invalid buffer"); diff --git a/include/Nazara/Core/Mutex.inl b/include/Nazara/Core/Mutex.inl index 7d0618071..fe4a77577 100644 --- a/include/Nazara/Core/Mutex.inl +++ b/include/Nazara/Core/Mutex.inl @@ -9,6 +9,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Mutex */ diff --git a/include/Nazara/Core/ObjectLibrary.inl b/include/Nazara/Core/ObjectLibrary.inl index 41497a808..e656a820e 100644 --- a/include/Nazara/Core/ObjectLibrary.inl +++ b/include/Nazara/Core/ObjectLibrary.inl @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ObjectRef * \brief Core class that represents a reference to an object */ @@ -20,7 +21,6 @@ namespace Nz * * \remark Produces a NazaraError if object not found */ - template ObjectRef ObjectLibrary::Get(const String& name) { @@ -35,7 +35,6 @@ namespace Nz * \brief Checks whether the library has the object with that name * \return true if it the case */ - template bool ObjectLibrary::Has(const String& name) { @@ -48,7 +47,6 @@ namespace Nz * \param name Name of the object * \param object Object to stock */ - template void ObjectLibrary::Register(const String& name, ObjectRef object) { @@ -61,7 +59,6 @@ namespace Nz * * \param name Name of the object */ - template ObjectRef ObjectLibrary::Query(const String& name) { @@ -77,7 +74,6 @@ namespace Nz * * \param name Name of the object */ - template void ObjectLibrary::Unregister(const String& name) { @@ -87,7 +83,7 @@ namespace Nz template bool ObjectLibrary::Initialize() { - return true; // Que faire + return true; // Nothing to do } template diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index 7799b6cbd..ad74b4f2e 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ObjectRef * \brief Core class that represents a reference to an object */ @@ -15,7 +16,6 @@ namespace Nz /*! * \brief Constructs a ObjectRef object by default */ - template ObjectRef::ObjectRef() : m_object(nullptr) @@ -27,7 +27,6 @@ namespace Nz * * \param object Pointer to handle like a reference (can be nullptr) */ - template ObjectRef::ObjectRef(T* object) : m_object(object) @@ -41,7 +40,6 @@ namespace Nz * * \param ref ObjectRef to assign into this */ - template ObjectRef::ObjectRef(const ObjectRef& ref) : m_object(ref.m_object) @@ -55,7 +53,6 @@ namespace Nz * * \param ref ObjectRef of type U to convert to type T */ - template template ObjectRef::ObjectRef(const ObjectRef& ref) : @@ -68,7 +65,6 @@ namespace Nz * * \param ref ObjectRef to move into this */ - template ObjectRef::ObjectRef(ObjectRef&& ref) noexcept : m_object(ref.m_object) @@ -79,7 +75,6 @@ namespace Nz /*! * \brief Destructs the object (remove a reference to the object when shared) */ - template ObjectRef::~ObjectRef() { @@ -91,7 +86,6 @@ namespace Nz * \brief Gets the underlying pointer * \return Underlying pointer */ - template T* ObjectRef::Get() const { @@ -102,7 +96,6 @@ namespace Nz * \brief Checks whether the reference is valid * \return true if reference is not nullptr */ - template bool ObjectRef::IsValid() const { @@ -113,7 +106,6 @@ namespace Nz * \brief Releases the handle of the pointer * \return Underlying pointer */ - template T* ObjectRef::Release() { @@ -130,7 +122,6 @@ namespace Nz * \brief Resets the content of the ObjectRef with another pointer * \return true if old handle is destroyed */ - template bool ObjectRef::Reset(T* object) { @@ -154,7 +145,6 @@ namespace Nz * * \param ref ObjectRef to swap */ - template ObjectRef& ObjectRef::Swap(ObjectRef& ref) { @@ -169,7 +159,6 @@ namespace Nz * * \see IsValid */ - template ObjectRef::operator bool() const { @@ -180,7 +169,6 @@ namespace Nz * \brief Dereferences the ObjectRef * \return Underlying pointer */ - template ObjectRef::operator T*() const { @@ -191,20 +179,18 @@ namespace Nz * \brief Dereferences the ObjectRef * \return Underlying pointer */ - template T* ObjectRef::operator->() const { return m_object; } - + /*! * \brief Assigns the object into this * \return A reference to this * * \param object Pointer to handle like a reference (can be nullptr) */ - template ObjectRef& ObjectRef::operator=(T* object) { @@ -219,7 +205,6 @@ namespace Nz * * \param ref The other ObjectRef */ - template ObjectRef& ObjectRef::operator=(const ObjectRef& ref) { @@ -234,7 +219,6 @@ namespace Nz * * \param ref ObjectRef of type U to convert */ - template template ObjectRef& ObjectRef::operator=(const ObjectRef& ref) @@ -252,7 +236,6 @@ namespace Nz * * \param ref ObjectRef to move in this */ - template ObjectRef& ObjectRef::operator=(ObjectRef&& ref) noexcept { @@ -267,12 +250,12 @@ namespace Nz namespace std { /*! + * \ingroup core * \brief Gives a hash representation of the object, specialisation of std * \return Hash of the ObjectRef * * \param object Object to hash */ - template struct hash> { diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index 8aeecc5b6..8124a7ed9 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -7,6 +7,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::PrimitiveList * \brief Core class that represents a geometric primitive */ @@ -19,7 +20,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -38,7 +38,6 @@ namespace Nz * \param rotation Rotation of the box * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeBox(lengths, subdivision, Matrix4f::Transform(position, rotation), uvCoords); @@ -53,7 +52,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -74,7 +72,6 @@ namespace Nz * \param rotation Rotation of the cone * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeCone(length, radius, subdivision, Matrix4f::Transform(position, rotation), uvCoords); @@ -88,7 +85,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -108,7 +104,6 @@ namespace Nz * \param rotation Rotation of the cubic sphere * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeCubicSphere(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords); @@ -122,7 +117,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -142,7 +136,6 @@ namespace Nz * \param rotation Rotation of the icosphere * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeIcoSphere(size, recursionLevel, Matrix4f::Transform(position, rotation), uvCoords); @@ -156,7 +149,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -174,7 +166,6 @@ namespace Nz * \param planeInfo Information for the plane * \param uvCoords Coordinates for texture */ - inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo, const Rectf& uvCoords) { MakePlane(size, subdivision, Matrix4f::Transform(planeInfo.distance * planeInfo.normal, Quaternionf::RotationBetween(Vector3f::Up(), planeInfo.normal)), uvCoords); @@ -189,7 +180,6 @@ namespace Nz * \param rotation Rotation of the plane * \param uvCoords Coordinates for texture */ - inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakePlane(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords); @@ -204,7 +194,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords) { matrix = transformMatrix; @@ -226,7 +215,6 @@ namespace Nz * \param rotation Rotation of the box * \param uvCoords Coordinates for texture */ - inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { MakeUVSphere(size, sliceCount, stackCount, Matrix4f::Transform(position, rotation), uvCoords); @@ -241,7 +229,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -260,7 +247,6 @@ namespace Nz * \param rotation Rotation of the box * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -279,7 +265,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -299,7 +284,6 @@ namespace Nz * \param rotation Rotation of the cone * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -317,7 +301,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -336,7 +319,6 @@ namespace Nz * \param rotation Rotation of the cubic sphere * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -354,7 +336,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -373,7 +354,6 @@ namespace Nz * \param rotation Rotation of the icosphere * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -391,7 +371,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -409,7 +388,6 @@ namespace Nz * \param planeInfo Information for the plane * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords) { Primitive primitive; @@ -428,7 +406,6 @@ namespace Nz * \param rotation Rotation of the plane * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; @@ -447,7 +424,6 @@ namespace Nz * \param transformMatrix Matrix to apply * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords) { Primitive primitive; @@ -467,7 +443,6 @@ namespace Nz * \param rotation Rotation of the box * \param uvCoords Coordinates for texture */ - inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) { Primitive primitive; diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index e58ec1b33..f16ab6d6e 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -12,7 +12,8 @@ namespace Nz { /*! - * \class Nz::ResourceLoader + * \ingroup core + * \class Nz::ResourceLoader * \brief Core class that represents a loader of resources */ @@ -22,7 +23,6 @@ namespace Nz * * \param extension Extension of the file */ - template bool ResourceLoader::IsExtensionSupported(const String& extension) { @@ -52,7 +52,6 @@ namespace Nz * \remark Produces a NazaraWarning if loader failed * \remark Produces a NazaraError if all loaders failed or no loader was found */ - template bool ResourceLoader::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters) { @@ -171,7 +170,6 @@ namespace Nz * \remark Produces a NazaraWarning if loader failed * \remark Produces a NazaraError if all loaders failed or no loader was found */ - template bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) { @@ -268,7 +266,6 @@ namespace Nz * \remark Produces a NazaraWarning if loader failed * \remark Produces a NazaraError if all loaders failed or no loader was found */ - template bool ResourceLoader::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters) { @@ -336,7 +333,6 @@ namespace Nz * \param fileLoader Optional function to load the data from a file in the resource * \param memoryLoader Optional function to load the data from a raw memory in the resource */ - template void ResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { @@ -368,7 +364,6 @@ namespace Nz * \param fileLoader Optional function to load the data from a file in the resource * \param memoryLoader Optional function to load the data from a raw memory in the resource */ - template void ResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { diff --git a/include/Nazara/Core/ResourceManager.inl b/include/Nazara/Core/ResourceManager.inl index 9c8dc903b..edc85068b 100644 --- a/include/Nazara/Core/ResourceManager.inl +++ b/include/Nazara/Core/ResourceManager.inl @@ -10,14 +10,14 @@ namespace Nz { /*! - * \class Nz::ResourceManager + * \ingroup core + * \class Nz::ResourceManager * \brief Core class that represents a resource manager */ /*! * \brief Clears the content of the manager */ - template void ResourceManager::Clear() { @@ -30,7 +30,6 @@ namespace Nz * * \param filePath Path to the asset that will be loaded */ - template ObjectRef ResourceManager::Get(const String& filePath) { @@ -63,7 +62,6 @@ namespace Nz * \brief Gets the defaults parameters for the load * \return Default parameters for loading from file */ - template const Parameters& ResourceManager::GetDefaultParameters() { @@ -73,7 +71,6 @@ namespace Nz /*! * \brief Purges the resource manager from every asset whose it is the only owner */ - template void ResourceManager::Purge() { @@ -97,7 +94,6 @@ namespace Nz * \param filePath Path for the resource * \param resource Object to associate with */ - template void ResourceManager::Register(const String& filePath, ObjectRef resource) { @@ -111,7 +107,6 @@ namespace Nz * * \param params Default parameters for loading from file */ - template void ResourceManager::SetDefaultParameters(const Parameters& params) { @@ -123,7 +118,6 @@ namespace Nz * * \param filePath Path for the resource */ - template void ResourceManager::Unregister(const String& filePath) { @@ -136,7 +130,6 @@ namespace Nz * \brief Initializes the resource manager * \return true */ - template bool ResourceManager::Initialize() { @@ -146,7 +139,6 @@ namespace Nz /*! * \brief Uninitialize the resource manager */ - template void ResourceManager::Uninitialize() { diff --git a/include/Nazara/Core/Signal.inl b/include/Nazara/Core/Signal.inl index de1609d78..466d87537 100644 --- a/include/Nazara/Core/Signal.inl +++ b/include/Nazara/Core/Signal.inl @@ -9,12 +9,13 @@ namespace Nz { /*! - * \class Nz::Signal + * \ingroup core + * \class Nz::Signal * \brief Core class that represents a signal, a list of objects waiting for its message */ /*! - * \brief Constructs a Signal object by default + * \brief Constructs a Signal object by default */ template @@ -24,7 +25,7 @@ namespace Nz } /*! - * \brief Constructs a Signal object by move semantic + * \brief Constructs a Signal object by move semantic * * \param signal Signal to move in this */ @@ -240,12 +241,12 @@ namespace Nz } /*! - * \class Nz::Signal::Connection + * \class Nz::Signal::Connection * \brief Core class that represents a connection attached to a signal */ /*! - * \brief Constructs a Signal::Connection object with a slot + * \brief Constructs a Signal::Connection object with a slot * * \param slot Slot of the listener */ @@ -293,12 +294,12 @@ namespace Nz } /*! - * \class Nz::Signal::ConnectionGuard + * \class Nz::Signal::ConnectionGuard * \brief Core class that represents a RAII for a connection attached to a signal */ /*! - * \brief Constructs a Signal::ConnectionGuard object with a connection + * \brief Constructs a Signal::ConnectionGuard object with a connection * * \param connection Connection for the scope */ @@ -310,7 +311,7 @@ namespace Nz } /*! - * \brief Constructs a Signal::ConnectionGuard object with a connection by move semantic + * \brief Constructs a Signal::ConnectionGuard object with a connection by move semantic * * \param connection Connection for the scope */ diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index 31e83addd..d81c1eac3 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -8,12 +8,13 @@ namespace Nz { /*! - * \class Nz::SparsePtr + * \ingroup core + * \class Nz::SparsePtr * \brief Core class that represents a pointer and the step between two elements */ /*! - * \brief Constructs a SparsePtr object by default + * \brief Constructs a SparsePtr object by default */ template @@ -23,7 +24,7 @@ namespace Nz } /*! - * \brief Constructs a SparsePtr object with a pointer + * \brief Constructs a SparsePtr object with a pointer * * \param ptr Pointer to data */ @@ -35,7 +36,7 @@ namespace Nz } /*! - * \brief Constructs a SparsePtr object with a pointer and a step + * \brief Constructs a SparsePtr object with a pointer and a step * * \param ptr Pointer to data * \param stride Step between two elements @@ -48,7 +49,7 @@ namespace Nz } /*! - * \brief Constructs a SparsePtr object from another type of SparsePtr + * \brief Constructs a SparsePtr object from another type of SparsePtr * * \param ptr Pointer to data of type U to convert to type T */ @@ -214,7 +215,7 @@ namespace Nz */ template - T* SparsePtr::operator->() const + T* SparsePtr::operator->() const { return reinterpret_cast(m_ptr); } diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index fa90682b0..aae7fe155 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \brief Constructs a Stream object with options * * \param streamOptions Options for the stream diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 40c08d315..aa4343371 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \brief Constructs a String object with a shared string by move semantic * * \param sharedString Shared string to move into this diff --git a/include/Nazara/Core/TaskScheduler.inl b/include/Nazara/Core/TaskScheduler.inl index ba64cfb1a..96e240081 100644 --- a/include/Nazara/Core/TaskScheduler.inl +++ b/include/Nazara/Core/TaskScheduler.inl @@ -7,6 +7,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::TaskScheduler * \brief Core class that represents a thread pool */ diff --git a/include/Nazara/Core/Thread.inl b/include/Nazara/Core/Thread.inl index f3de4ae24..f372c803f 100644 --- a/include/Nazara/Core/Thread.inl +++ b/include/Nazara/Core/Thread.inl @@ -8,12 +8,13 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Thread * \brief Core class that represents a thread */ /*! - * \brief Constructs a Thread object with a function + * \brief Constructs a Thread object with a function * * \param function Task the thread will execute in parallel */ @@ -25,7 +26,7 @@ namespace Nz } /*! - * \brief Constructs a Thread object with a function and its parameters + * \brief Constructs a Thread object with a function and its parameters * * \param function Task the thread will execute in parallel * \param args Arguments of the function @@ -38,7 +39,7 @@ namespace Nz } /*! - * \brief Constructs a Thread object with a member function and its object + * \brief Constructs a Thread object with a member function and its object * * \param function Task the thread will execute in parallel * \param object Object on which the method will be called diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index f18ee119e..e7e205e45 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -99,6 +99,7 @@ namespace Nz } /*! + * \ingroup math * \brief Approaches the objective, beginning with value and with increment * \return The nearest value of the objective you can get with the value and the increment for one step * @@ -120,6 +121,7 @@ namespace Nz } /*! + * \ingroup math * \brief Clamps value between min and max and returns the expected value * \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval * @@ -135,6 +137,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets number of bits set in the number * \return The number of bits set to 1 * @@ -157,6 +160,7 @@ namespace Nz } /*! + * \ingroup math * \brief Converts degree to radian * \return The representation in radian of the angle in degree (0..2*pi) * @@ -170,6 +174,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the unit from degree and convert it according to NAZARA_MATH_ANGLE_RADIAN * \return Express the degrees * @@ -187,6 +192,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the unit from radian and convert it according to NAZARA_MATH_ANGLE_RADIAN * \return Express the radians * @@ -204,6 +210,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the nearest power of two for the number * \return First power of two containing the number * @@ -222,6 +229,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits * @@ -249,6 +257,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits * @@ -270,6 +279,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits * @@ -285,6 +295,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits * @@ -301,6 +312,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits * @@ -316,6 +328,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits * @@ -332,6 +345,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits + 1 for the dot * @@ -346,6 +360,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits + 1 for the dot * @@ -360,6 +375,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the number of digits to represent the number in base 10 * \return Number of digits + 1 for the dot * @@ -374,6 +390,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the log in base 2 of integral number * \return Log of the number (floor) * @@ -391,6 +408,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the log in base 2 of integral number, only works for power of two ! * \return Log of the number * @@ -408,6 +426,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the power of integrals * \return base^exponent for integral * @@ -426,6 +445,7 @@ namespace Nz } /*! + * \ingroup math * \brief Interpolates the value to other one with a factor of interpolation * \return A new value which is the interpolation of two values * @@ -446,6 +466,7 @@ namespace Nz } /*! + * \ingroup math * \brief Multiplies X and Y, then add Z * \return The result of X * Y + Z * @@ -487,6 +508,7 @@ namespace Nz #endif /*! + * \ingroup math * \brief Normalizes the angle * \return Normalized value between 0..2*(pi if radian or 180 if degrees) * @@ -512,6 +534,7 @@ namespace Nz } /*! + * \ingroup math * \brief Checks whether two numbers are equal * \return true if they are equal within a certain epsilon * @@ -527,6 +550,7 @@ namespace Nz } /*! + * \ingroup math * \brief Checks whether two numbers are equal * \return true if they are equal within the max difference * @@ -547,6 +571,7 @@ namespace Nz } /*! + * \ingroup math * \brief Converts the number to String * \return String representation of the number * @@ -598,6 +623,7 @@ namespace Nz } /*! + * \ingroup math * \brief Converts radian to degree * \return The representation in degree of the angle in radian (0..360) * @@ -611,6 +637,7 @@ namespace Nz } /*! + * \ingroup math * \brief Converts the string to number * \return Number which is represented by the string * @@ -672,6 +699,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the degree from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN * \return Express in degrees * @@ -689,6 +717,7 @@ namespace Nz } /*! + * \ingroup math * \brief Gets the radian from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN * \return Express in radians * diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 4cde59731..4047769dc 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -15,14 +15,15 @@ namespace Nz { /*! - * \class Nz::BoundingVolume + * \ingroup math + * \class Nz::BoundingVolume * \brief Math class that represents a bounding volume, a combination of a box and an oriented box * * \remark You need to call Update not to have undefined behaviour */ /*! - * \brief Constructs a BoundingVolume object by default + * \brief Constructs a BoundingVolume object by default * * \remark extend is set to Extend_Null, aabb and obb are uninitialized */ @@ -34,7 +35,7 @@ namespace Nz } /*! - * \brief Constructs a BoundingVolume object from Extend + * \brief Constructs a BoundingVolume object from Extend * \param Extend Extend of the volume part of enumeration Extend * * \remark Aabb and obb are uninitialized @@ -47,7 +48,7 @@ namespace Nz } /*! - * \brief Constructs a BoundingVolume object from its position and sizes + * \brief Constructs a BoundingVolume object from its position and sizes * * \param X X component of position * \param Y Y component of position @@ -66,7 +67,7 @@ namespace Nz } /*! - * \brief Constructs a BoundingVolume object from a box + * \brief Constructs a BoundingVolume object from a box * * \param box Box object * @@ -80,7 +81,7 @@ namespace Nz } /*! - * \brief Constructs a BoundingVolume object from an oriented box + * \brief Constructs a BoundingVolume object from an oriented box * * \param orientedBox OrientedBox object * @@ -94,7 +95,7 @@ namespace Nz } /*! - * \brief Constructs a BoundingVolume object from two vectors representing point of the space + * \brief Constructs a BoundingVolume object from two vectors representing point of the space * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum * * \param vec1 First point @@ -110,7 +111,7 @@ namespace Nz } /*! - * \brief Constructs a BoundingVolume object from another type of BoundingVolume + * \brief Constructs a BoundingVolume object from another type of BoundingVolume * * \param volume BoundingVolume of type U to convert to type T */ @@ -272,7 +273,7 @@ namespace Nz } /*! - * \brief Sets a BoundingVolume object from two vectors representing point of the space + * \brief Sets a BoundingVolume object from two vectors representing point of the space * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum * * \param vec1 First point diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index a377b7d8f..8c8d655ef 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -13,12 +13,13 @@ namespace Nz { /*! - * \class Nz::Box + * \ingroup math + * \class Nz::Box * \brief Math class that represents a three dimensional box */ /*! - * \brief Constructs a Box object from its width, height and depth + * \brief Constructs a Box object from its width, height and depth * * \param Width Width of the box (following X) * \param Height Height of the box (following Y) @@ -51,7 +52,7 @@ namespace Nz } /*! - * \brief Constructs a Box object from an array of six elements + * \brief Constructs a Box object from an array of six elements * * \param vec[6] vec[0] is X position, vec[1] is Y position, vec[2] is Z position, vec[3] is width, vec[4] is height and vec[5] is depth */ @@ -63,7 +64,7 @@ namespace Nz } /*! - * \brief Constructs a Box object from a Rect + * \brief Constructs a Box object from a Rect * * \param rect Rectangle which describes (X, Y) position and (width, height) lenghts * @@ -77,7 +78,7 @@ namespace Nz } /*! - * \brief Constructs a Box object from a vector representing width, height and depth + * \brief Constructs a Box object from a vector representing width, height and depth * * \param lengths (Width, Height, Depth) of the box * @@ -91,7 +92,7 @@ namespace Nz } /*! - * \brief Constructs a Box object from two vectors representing point of the space + * \brief Constructs a Box object from two vectors representing point of the space * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum * * \param vec1 First point @@ -105,7 +106,7 @@ namespace Nz } /*! - * \brief Constructs a Box object from another type of Box + * \brief Constructs a Box object from another type of Box * * \param box Box of type U to convert to type T */ @@ -540,7 +541,7 @@ namespace Nz } /*! - * \brief Constructs a Box object from its position and sizes + * \brief Constructs a Box object from its position and sizes * * \param X X component of position * \param Y Y component of position diff --git a/include/Nazara/Math/Config.hpp b/include/Nazara/Math/Config.hpp index 3d27848af..a4891a18a 100644 --- a/include/Nazara/Math/Config.hpp +++ b/include/Nazara/Math/Config.hpp @@ -28,6 +28,11 @@ #ifndef NAZARA_CONFIG_MATH_HPP #define NAZARA_CONFIG_MATH_HPP +/*! +* \defgroup math (NazaraMath) Mathematics module +* 2D/3D mathematics module including matrix, vector, box, sphere, quaternion, ... +*/ + /// Each modification of a paramater of the module needs a recompilation of the unit // Define the radian as unit for angles diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index 3e4eabc6a..5c442f6c9 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -16,14 +16,15 @@ namespace Nz { /*! - * \class Nz::Vector4 + * \ingroup math + * \class Nz::EulerAngles * \brief Math class that represents an Euler angle. Those describe a rotation transformation by rotating an object on its various axes in specified amounts per axis, and a specified axis order * * \remark Rotation are "left-handed", it means that you take your left hand, put your thumb finger in the direction you want and you other fingers represent the way of rotating */ /*! - * \brief Constructs a EulerAngles object from its components + * \brief Constructs a EulerAngles object from its components * * \param P Pitch component = X axis * \param Y Yaw component = Y axis @@ -37,7 +38,7 @@ namespace Nz } /*! - * \brief Constructs a EulerAngles object from an array of three elements + * \brief Constructs a EulerAngles object from an array of three elements * * \param angles[3] angles[0] is pitch component, angles[1] is yaw component and angles[2] is roll component */ @@ -49,7 +50,7 @@ namespace Nz } /*! - * \brief Constructs a EulerAngles object from a quaternion + * \brief Constructs a EulerAngles object from a quaternion * * \param quat Quaternion representing a rotation of space */ @@ -61,7 +62,7 @@ namespace Nz } /*! - * \brief Constructs a EulerAngles object from another type of EulerAngles + * \brief Constructs a EulerAngles object from another type of EulerAngles * * \param angles EulerAngles of type U to convert to type T */ diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 35e63ca98..4ff2b8f1b 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -17,14 +17,15 @@ namespace Nz { /*! - * \class Nz::Frustum + * \ingroup math + * \class Nz::Frustum * \brief Math class that represents a frustum in the three dimensional vector space * * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process */ /*! - * \brief Constructs a Frustum object from another type of Frustum + * \brief Constructs a Frustum object from another type of Frustum * * \param frustum Frustum of type U to convert to type T */ diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index a5b4fb631..935387eba 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -22,14 +22,15 @@ namespace Nz { /*! - * \class Nz::Matrix4 + * \ingroup math + * \class Nz::Matrix4 * \brief Math class that represents a transformation of the four dimensional vector space with the notion of projectivity * * \remark Matrix4 is said to be "row-major" and affine if last column is made of (0, 0, 0, 1) */ /*! - * \brief Constructs a Matrix4 object from its components + * \brief Constructs a Matrix4 object from its components * * \param rIJ Matrix components at index(I, J) */ @@ -47,7 +48,7 @@ namespace Nz } /*! - * \brief Constructs a Matrix4 object from an array of sixteen elements + * \brief Constructs a Matrix4 object from an array of sixteen elements * * \param matrix[16] Matrix components */ @@ -59,7 +60,7 @@ namespace Nz } /*! - * \brief Constructs a Matrix4 object from another type of Matrix4 + * \brief Constructs a Matrix4 object from another type of Matrix4 * * \param matrix Matrix4 of type U to convert to type T */ @@ -1785,7 +1786,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix) */ template -Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) +Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) { return matrix * scale; } diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index c1668118c..188b6d8fc 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -14,14 +14,15 @@ namespace Nz { /*! - * \class Nz::OrientedBox + * \ingroup math + * \class Nz::OrientedBox * \brief Math class that represents an oriented three dimensional box * * \remark You need to call Update not to have undefined behaviour */ /*! - * \brief Constructs a OrientedBox object from its position and sizes + * \brief Constructs a OrientedBox object from its position and sizes * * \param X X component of position * \param Y Y component of position @@ -38,7 +39,7 @@ namespace Nz } /*! - * \brief Constructs a OrientedBox object from a box + * \brief Constructs a OrientedBox object from a box * * \param box Box object */ @@ -50,7 +51,7 @@ namespace Nz } /*! - * \brief Constructs a OrientedBox object from two vectors representing point of the space + * \brief Constructs a OrientedBox object from two vectors representing point of the space * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum * * \param vec1 First point @@ -64,7 +65,7 @@ namespace Nz } /*! - * \brief Constructs a OrientedBox object from another type of OrientedBox + * \brief Constructs a OrientedBox object from another type of OrientedBox * * \param orientedBox OrientedBox of type U to convert to type T */ @@ -178,7 +179,7 @@ namespace Nz } /*! - * \brief Sets a OrientedBox object from two vectors representing point of the space + * \brief Sets a OrientedBox object from two vectors representing point of the space * (X, Y, Z) will be the components minimum of the two vectors and the (width, height, depth) will be the components maximum - minimum * * \param vec1 First point diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 9b29ab48a..29bd829b2 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -12,14 +12,15 @@ namespace Nz { /*! - * \class Nz::Vector4 + * \ingroup math + * \class Nz::Plane * \brief Math class that represents a plane in 3D * * \remark The convention used in this class is: If you ask for plane with normal (0, 1, 0) and distance 1, you will get 0 * X + 1 * Y + 0 * Z - 1 = 0 or Y = 1. Notice the sign minus before the distance on the left side of the equation */ /*! - * \brief Constructs a Plane object from its components + * \brief Constructs a Plane object from its components * * \param normalX X component of the normal * \param normalY Y component of the normal @@ -34,7 +35,7 @@ namespace Nz } /*! - * \brief Constructs a Plane object from an array of four elements + * \brief Constructs a Plane object from an array of four elements * * \param plane[4] plane[0] is X component, plane[1] is Y component, plane[2] is Z component and plane[3] is D */ @@ -46,7 +47,7 @@ namespace Nz } /*! - * \brief Constructs a Plane object from a normal and a distance + * \brief Constructs a Plane object from a normal and a distance * * \param Normal normal of the vector * \param D Distance to origin @@ -59,7 +60,7 @@ namespace Nz } /*! - * \brief Constructs a Plane object from a normal and a point + * \brief Constructs a Plane object from a normal and a point * * \param Normal Normal of the plane * \param point Point which verifies the equation of the plane @@ -72,7 +73,7 @@ namespace Nz } /*! - * \brief Constructs a Plane object from three points + * \brief Constructs a Plane object from three points * * \param point1 First point * \param point2 Second point @@ -88,7 +89,7 @@ namespace Nz } /*! - * \brief Constructs a Plane object from another type of Plane + * \brief Constructs a Plane object from another type of Plane * * \param plane Plane of type U to convert to type T */ diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index ea1ce4d3e..75e3966d3 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -16,14 +16,15 @@ namespace Nz { /*! - * \class Nz::Quaternion + * \ingroup math + * \class Nz::Quaternion * \brief Math class that represents an element of the quaternions * * \remark The quaternion is meant to be 'unit' to represent rotations in a three dimensional space */ /*! - * \brief Constructs a Quaternion object from its components + * \brief Constructs a Quaternion object from its components * * \param W W component * \param X X component @@ -38,7 +39,7 @@ namespace Nz } /*! - * \brief Constructs a Quaternion object from a EulerAngles + * \brief Constructs a Quaternion object from a EulerAngles * * \param angles Easier representation of rotation of space * @@ -52,7 +53,7 @@ namespace Nz } /*! - * \brief Constructs a Quaternion object from an angle and a direction + * \brief Constructs a Quaternion object from an angle and a direction * * \param angle Unit depends of NAZARA_MATH_ANGLE_RADIAN * \param axis Vector3 which represents a direction, no need to be normalized @@ -65,7 +66,7 @@ namespace Nz } /*! - * \brief Constructs a Quaternion object from an array of four elements + * \brief Constructs a Quaternion object from an array of four elements * * \param quat[4] quat[0] is W component, quat[1] is X component, quat[2] is Y component and quat[3] is Z component */ @@ -85,7 +86,7 @@ namespace Nz */ /*! - * \brief Constructs a Quaternion object from another type of Quaternion + * \brief Constructs a Quaternion object from another type of Quaternion * * \param quat Quaternion of type U to convert to type T */ diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index de2b2d726..e83c39488 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -11,14 +11,15 @@ namespace Nz { /*! - * \class Nz::Ray + * \ingroup math + * \class Nz::Ray * \brief Math class that represents a ray or a straight line in 3D space * * This ray is meant to be understood like origin + lambda * direction, where lambda is a real positive parameter */ /*! - * \brief Constructs a Ray object from its position and direction + * \brief Constructs a Ray object from its position and direction * * \param X X position * \param Y Y position @@ -35,7 +36,7 @@ namespace Nz } /*! - * \brief Constructs a Ray object from two Vector3 + * \brief Constructs a Ray object from two Vector3 * * \param Origin Vector which represents the origin of the ray * \param Direction Vector which represents the direction of the ray @@ -48,7 +49,7 @@ namespace Nz } /*! - * \brief Constructs a Ray object from two arrays of three elements + * \brief Constructs a Ray object from two arrays of three elements * * \param Origin[3] Origin[0] is X position, Origin[1] is Y position and Origin[2] is Z position * \param Direction[3] Direction[0] is X direction, Direction[1] is Y direction and Direction[2] is Z direction @@ -61,7 +62,7 @@ namespace Nz } /*! - * \brief Constructs a Ray object from the intersection of two planes + * \brief Constructs a Ray object from the intersection of two planes * * \param planeOne First plane * \param planeTwo Second secant plane @@ -77,7 +78,7 @@ namespace Nz } /*! - * \brief Constructs a Ray object from another type of Ray + * \brief Constructs a Ray object from another type of Ray * * \param ray Ray of type U to convert to type T */ @@ -90,7 +91,7 @@ namespace Nz } /*! - * \brief Constructs a Ray object from two Vector3 from another type of Ray + * \brief Constructs a Ray object from two Vector3 from another type of Ray * * \param Origin Origin of type U to convert to type T * \param Direction Direction of type U to convert to type T diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 82c9e9f3f..9a2737a02 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -13,14 +13,15 @@ namespace Nz { /*! - * \class Nz::Rect + * \ingroup math + * \class Nz::Rect * \brief Math class that represents an axis-aligned rectangle in two dimensions * * \remark The basis is said to be "left-hand". It means that with your left hand, the thumb is X positive, the index finger Y positive pointing to the bottom */ /*! - * \brief Constructs a Rect object from its width and height + * \brief Constructs a Rect object from its width and height * * \param Width Width of the rectangle (following X) * \param Height Height of the rectangle (following Y) @@ -35,7 +36,7 @@ namespace Nz } /*! - * \brief Constructs a Rect object from its position, width and height + * \brief Constructs a Rect object from its position, width and height * * \param X X position * \param Y Y position @@ -50,7 +51,7 @@ namespace Nz } /*! - * \brief Constructs a Rect object from an array of four elements + * \brief Constructs a Rect object from an array of four elements * * \param vec[4] vec[0] is X position, vec[1] is Y position, vec[2] is width and vec[3] is height */ @@ -62,7 +63,7 @@ namespace Nz } /*! - * \brief Constructs a Rect object from a vector representing width and height + * \brief Constructs a Rect object from a vector representing width and height * * \param lengths (Width, Height) of the rectangle * @@ -76,7 +77,7 @@ namespace Nz } /*! - * \brief Constructs a Rect object from two vectors representing point of the space + * \brief Constructs a Rect object from two vectors representing point of the space * (X, Y) will be the components minimum of the two vectors and the width and height will be the components maximum - minimum * * \param vec1 First point @@ -90,7 +91,7 @@ namespace Nz } /*! - * \brief Constructs a Rect object from another type of Rect + * \brief Constructs a Rect object from another type of Rect * * \param rect Rect of type U to convert to type T */ @@ -504,7 +505,7 @@ namespace Nz } /*! - * \brief Sets a Rect object from two vectors representing point of the space + * \brief Sets a Rect object from two vectors representing point of the space * (X, Y) will be the components minimum of the two vectors and the width and height will be the components maximum - minimum * \return A reference to this rectangle * diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 062a7b271..eac46d76c 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -14,12 +14,13 @@ namespace Nz { /*! - * \class Nz::Sphere + * \ingroup math + * \class Nz::Sphere * \brief Math class that represents a sphere "S2" in a three dimensional euclidean space */ /*! - * \brief Constructs a Sphere object from its center position and radius + * \brief Constructs a Sphere object from its center position and radius * * \param X X position * \param Y Y position @@ -41,7 +42,7 @@ namespace Nz */ /*! - * \brief Constructs a Sphere object from its position and radius + * \brief Constructs a Sphere object from its position and radius * * \param center Center of the sphere * \param Radius Half of the diameter @@ -54,7 +55,7 @@ namespace Nz } /*! - * \brief Constructs a Sphere object from an array of four elements + * \brief Constructs a Sphere object from an array of four elements * * \param sphere[4] sphere[0] is X component, sphere[1] is Y component, sphere[2] is Z component and sphere[3] is radius */ @@ -66,7 +67,7 @@ namespace Nz } /*! - * \brief Constructs a Sphere object from another type of Sphere + * \brief Constructs a Sphere object from another type of Sphere * * \param sphere Sphere of type U to convert to type T */ diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 1876087f5..45e8d8f5d 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -14,12 +14,13 @@ namespace Nz { /*! - * \class Nz::Vector2 + * \ingroup math + * \class Nz::Vector2 * \brief Math class that represents an element of the two dimensional vector space */ /*! - * \brief Constructs a Vector2 object from its coordinates + * \brief Constructs a Vector2 object from its coordinates * * \param X X component * \param Y Y component @@ -32,7 +33,7 @@ namespace Nz } /*! - * \brief Constructs explicitely a Vector2 object from its "scale" + * \brief Constructs explicitely a Vector2 object from its "scale" * * \param scale X component = Y component */ @@ -44,7 +45,7 @@ namespace Nz } /*! - * \brief Constructs a Vector2 object from an array of two elements + * \brief Constructs a Vector2 object from an array of two elements * * \param vec[2] vec[0] is X component and vec[1] is Y component */ @@ -56,7 +57,7 @@ namespace Nz } /*! - * \brief Constructs a Vector2 object from another type of Vector2 + * \brief Constructs a Vector2 object from another type of Vector2 * * \param vec Vector of type U to convert to type T */ @@ -69,7 +70,7 @@ namespace Nz } /*! - * \brief Constructs a Vector2 object from a Vector3 + * \brief Constructs a Vector2 object from a Vector3 * * \param vec Vector3 where only the first two components are taken */ @@ -81,7 +82,7 @@ namespace Nz } /*! - * \brief Constructs a Vector2 object from a Vector4 + * \brief Constructs a Vector2 object from a Vector4 * * \param vec Vector4 where only the first two components are taken */ @@ -988,7 +989,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec) */ template -Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) +Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) { return Nz::Vector2(scale * vec.x, scale * vec.y); } diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index a1807c902..f25fc5ba4 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -14,14 +14,15 @@ namespace Nz { /*! - * \class Nz::Vector2 + * \ingroup math + * \class Nz::Vector3 * \brief Math class that represents an element of the three dimensional vector space * * \remark The basis is said to be "right-hand". It means that with your right hand, the thumb is X positive, the index finger Y positive and the middle finger (pointing to you) Z positive */ /*! - * \brief Constructs a Vector3 object from its coordinates + * \brief Constructs a Vector3 object from its coordinates * * \param X X component * \param Y Y component @@ -35,7 +36,7 @@ namespace Nz } /*! - * \brief Constructs a Vector3 object from a component and a Vector2 + * \brief Constructs a Vector3 object from a component and a Vector2 * * \param X X component * \param vec vec.X = Y component and vec.y = Z component @@ -48,7 +49,7 @@ namespace Nz } /*! - * \brief Constructs explicitely a Vector3 object from its "scale" + * \brief Constructs explicitely a Vector3 object from its "scale" * * \param scale X component = Y component = Z component */ @@ -60,7 +61,7 @@ namespace Nz } /*! - * \brief Constructs a Vector3 object from an array of three elements + * \brief Constructs a Vector3 object from an array of three elements * * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component */ @@ -72,7 +73,7 @@ namespace Nz } /*! - * \brief Constructs a Vector3 object from a Vector2 and a component + * \brief Constructs a Vector3 object from a Vector2 and a component * * \param vec vec.X = X component and vec.y = Y component * \param Z Z component @@ -85,7 +86,7 @@ namespace Nz } /*! - * \brief Constructs a Vector3 object from another type of Vector3 + * \brief Constructs a Vector3 object from another type of Vector3 * * \param vec Vector of type U to convert to type T */ @@ -98,7 +99,7 @@ namespace Nz } /*! - * \brief Constructs a Vector3 object from a Vector4 + * \brief Constructs a Vector3 object from a Vector4 * * \param vec Vector4 where only the first three components are taken */ @@ -1299,7 +1300,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec) */ template -Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) +Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) { return Nz::Vector3(scale * vec.x, scale * vec.y, scale * vec.z); } diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index c5127b34e..bdf2bd64f 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -16,12 +16,13 @@ namespace Nz { /*! - * \class Nz::Vector4 + * \ingroup math + * \class Nz::Vector4 * \brief Math class that represents an element of the three dimensional vector space with the notion of projectivity. When the fourth component is 1, it describes an 'usual' point and when it is 0, it represents the point at infinity */ /*! - * \brief Constructs a Vector4 object from its coordinates + * \brief Constructs a Vector4 object from its coordinates * * \param X X component * \param Y Y component @@ -36,7 +37,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from two components and a Vector2 + * \brief Constructs a Vector4 object from two components and a Vector2 * * \param X X component * \param Y Y component @@ -50,7 +51,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from one component, a Vector2 and one component + * \brief Constructs a Vector4 object from one component, a Vector2 and one component * * \param X X component * \param vec vec.X = Y component and vec.y = Z component @@ -64,7 +65,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from one component and a Vector3 + * \brief Constructs a Vector4 object from one component and a Vector3 * * \param X X component * \param vec vec.X = Y component, vec.y = Z component and vec.z = W component @@ -77,7 +78,7 @@ namespace Nz } /*! - * \brief Constructs explicitely a Vector4 object from its "scale" + * \brief Constructs explicitely a Vector4 object from its "scale" * * \param scale X component = Y component = Z component = W component */ @@ -89,7 +90,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from an array of four elements + * \brief Constructs a Vector4 object from an array of four elements * * \param vec[4] vec[0] is X component, vec[1] is Y component, vec[2] is Z component and vec[3] is W component */ @@ -101,7 +102,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from a Vector2 and two components + * \brief Constructs a Vector4 object from a Vector2 and two components * * \param vec vec.X = X component and vec.y = Y component * \param Z Z component @@ -115,7 +116,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from one component and a Vector3 + * \brief Constructs a Vector4 object from one component and a Vector3 * * \param vec vec.X = X component, vec.y = Y component and vec.z = Z component * \param W W component @@ -128,7 +129,7 @@ namespace Nz } /*! - * \brief Constructs a Vector4 object from another type of Vector4 + * \brief Constructs a Vector4 object from another type of Vector4 * * \param vec Vector of type U to convert to type T */ @@ -1037,7 +1038,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec) template -Nz::Vector4 operator*(T scale, const Nz::Vector4& vec) +Nz::Vector4 operator*(T scale, const Nz::Vector4& vec) { return Nz::Vector4(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w); } diff --git a/src/Nazara/Core/AbstractHash.cpp b/src/Nazara/Core/AbstractHash.cpp index 60f2f42cb..419ba74e9 100644 --- a/src/Nazara/Core/AbstractHash.cpp +++ b/src/Nazara/Core/AbstractHash.cpp @@ -18,7 +18,8 @@ namespace Nz { /*! - * \class Nz::AbstractHash + * \ingroup core + * \class Nz::AbstractHash * \brief Core class that represents the behaviour of the hash classes * * \remark This class is abstract diff --git a/src/Nazara/Core/AbstractLogger.cpp b/src/Nazara/Core/AbstractLogger.cpp index 06695a928..ceac9eff8 100644 --- a/src/Nazara/Core/AbstractLogger.cpp +++ b/src/Nazara/Core/AbstractLogger.cpp @@ -21,7 +21,8 @@ namespace Nz } /*! - * \class Nz::AbstractLogger + * \ingroup core + * \class Nz::AbstractLogger * \brief Core class that represents the behaviour of the log classes * * \remark This class is abstract diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 9763e6336..e505f13f2 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -10,6 +10,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ByteArray * \brief Core class that represents an array of bytes */ diff --git a/src/Nazara/Core/ByteStream.cpp b/src/Nazara/Core/ByteStream.cpp index 1b0fc853e..cf5a045a9 100644 --- a/src/Nazara/Core/ByteStream.cpp +++ b/src/Nazara/Core/ByteStream.cpp @@ -12,6 +12,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ByteStream * \brief Core class that represents a stream of bytes */ diff --git a/src/Nazara/Core/Clock.cpp b/src/Nazara/Core/Clock.cpp index ef4689d50..60482b18e 100644 --- a/src/Nazara/Core/Clock.cpp +++ b/src/Nazara/Core/Clock.cpp @@ -42,6 +42,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::Clock * \brief Utility class that measure the elapsed time */ @@ -52,7 +53,6 @@ namespace Nz * \param startingValue The starting time value, in microseconds * \param paused The clock pause state */ - Clock::Clock(UInt64 startingValue, bool paused) : m_elapsedTime(startingValue), m_refTime(GetElapsedMicroseconds()), @@ -66,7 +66,6 @@ namespace Nz * * \see GetMicroseconds, GetMilliseconds */ - float Clock::GetSeconds() const { return GetMicroseconds()/1000000.f; @@ -78,7 +77,6 @@ namespace Nz * * \see GetMilliseconds, GetSeconds */ - UInt64 Clock::GetMicroseconds() const { NazaraLock(m_mutex); @@ -96,7 +94,6 @@ namespace Nz * * \see GetMicroseconds, GetSeconds */ - UInt64 Clock::GetMilliseconds() const { return GetMicroseconds()/1000; @@ -108,7 +105,6 @@ namespace Nz * * \see Pause, Unpause */ - bool Clock::IsPaused() const { NazaraLock(m_mutex); @@ -124,7 +120,6 @@ namespace Nz * * \see IsPaused, Unpause */ - void Clock::Pause() { NazaraLock(m_mutex); @@ -140,7 +135,6 @@ namespace Nz * \brief Restart the clock * Restarts the clock, putting it's time counter back to zero (as if the clock got constructed). */ - void Clock::Restart() { NazaraLock(m_mutex); @@ -158,7 +152,6 @@ namespace Nz * * \see IsPaused, Unpause */ - void Clock::Unpause() { NazaraLock(m_mutex); diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index c01b47722..0730ea829 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -19,6 +19,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ConditionVariable * \brief Core class that represents a condition variable * diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 26a451512..1ccb35212 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -14,7 +14,8 @@ namespace Nz { /*! - * \class Nz::CoreCore + * \ingroup core + * \class Nz::Core * \brief Core class that represents the module initializer of Core */ diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index b076b38d7..b48930419 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -35,6 +35,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::Directory * \brief Core class that represents a directory */ diff --git a/src/Nazara/Core/DynLib.cpp b/src/Nazara/Core/DynLib.cpp index 3261f0959..515f437b4 100644 --- a/src/Nazara/Core/DynLib.cpp +++ b/src/Nazara/Core/DynLib.cpp @@ -26,6 +26,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::DynLib * \brief Core class that represents a dynamic library loader */ diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index 59a8b72fb..ae6f0cc09 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -19,6 +19,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Error * \brief Core class that represents an error */ diff --git a/src/Nazara/Core/ErrorFlags.cpp b/src/Nazara/Core/ErrorFlags.cpp index d29efbc5a..003e37a23 100644 --- a/src/Nazara/Core/ErrorFlags.cpp +++ b/src/Nazara/Core/ErrorFlags.cpp @@ -9,6 +9,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ErrorFlags * \brief Core class that represents flags for error */ diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 55587c9e0..c03fb7b7f 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -31,6 +31,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::File * \brief Core class that represents a file */ diff --git a/src/Nazara/Core/FileLogger.cpp b/src/Nazara/Core/FileLogger.cpp index 6a94787bd..bac0cb099 100644 --- a/src/Nazara/Core/FileLogger.cpp +++ b/src/Nazara/Core/FileLogger.cpp @@ -13,6 +13,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::FileLogger * \brief Core class that represents a file logger */ diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 69e3a1333..e43e07572 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -17,6 +17,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::GuillotineBinPack * \brief Core class that represents the "Guillotine problem", combination of the "Bin packing problem" and the "cutting stock" */ diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index af7f47e5d..1fbd1a04a 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -83,6 +83,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::HardwareInfo * \brief Core class that represents the info we can get from hardware */ diff --git a/src/Nazara/Core/LockGuard.cpp b/src/Nazara/Core/LockGuard.cpp index 31c1fe559..e714f05f7 100644 --- a/src/Nazara/Core/LockGuard.cpp +++ b/src/Nazara/Core/LockGuard.cpp @@ -9,6 +9,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::LockGuard * \brief Core class that represents a mutex wrapper that provides a convenient RAII-style mechanism */ diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index 1a658c97e..9e6b13353 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -16,6 +16,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::Log * \brief Core class that represents a logger */ diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index 20dc17fa8..5ee1755d7 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -67,6 +67,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::MemoryManager * \brief Core class that represents a manager for the memory */ diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 7940fee8a..bb77f35f8 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -11,6 +11,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::MemoryStream * \brief Core class that represents a stream of memory */ diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index a636eb9a8..02c8b26c2 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -10,6 +10,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::MemoryView * \brief Core class that represents a view of the memory behaving like a stream */ @@ -134,7 +135,7 @@ namespace Nz { std::size_t endPos = static_cast(m_pos + size); if (endPos > m_size) - size = m_size - m_pos; + size = static_cast(m_size - m_pos); NazaraAssert(buffer, "Invalid buffer"); diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index 2d17276f1..68c94a8cf 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -18,6 +18,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Mutex * \brief Core class that represents a binary semaphore, a mutex * diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 1244b8b2c..405ebd1cd 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -13,6 +13,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::ParameterList * \brief Core class that represents a list of parameters */ diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index 04fcafac7..24fbafcfb 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -25,6 +25,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::PluginManager * \brief Core class that represents a manager for plugin */ diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index 644f46e66..a8d406b94 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -9,6 +9,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::PrimitiveList * \brief Core class that represents a list of geometric primitives */ diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index f2ef2b926..31e749515 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -17,6 +17,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::RefCounted * \brief Core class that represents a reference with a counter */ diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 23fa6ea22..82ef768d1 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Resource * \brief Core class that represents a resource */ diff --git a/src/Nazara/Core/Semaphore.cpp b/src/Nazara/Core/Semaphore.cpp index c5d9cc5b7..1b2194095 100644 --- a/src/Nazara/Core/Semaphore.cpp +++ b/src/Nazara/Core/Semaphore.cpp @@ -17,6 +17,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Semaphore * \brief Core class that represents a counting semaphore */ diff --git a/src/Nazara/Core/StdLogger.cpp b/src/Nazara/Core/StdLogger.cpp index 783957ef1..e38daa077 100644 --- a/src/Nazara/Core/StdLogger.cpp +++ b/src/Nazara/Core/StdLogger.cpp @@ -21,6 +21,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::StdLogger * \brief Core class that represents a logger writing to standard output (stdout, stderr) */ diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 3ddcb9fc7..b36b67d85 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -12,6 +12,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::Stream * \brief Core class that represents a stream */ diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 74c2afe80..8abeb2d02 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -77,6 +77,7 @@ namespace Nz } /*! + * \ingroup core * \class Nz::String * \brief Core class that represents a string */ diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index a76dc9d86..ebd509c65 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -8,6 +8,7 @@ namespace Nz { /*! + * \ingroup core * \class Nz::StringStream * \brief Core class that represents a stream of strings */ diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index 108e120b1..a29436407 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -25,7 +25,8 @@ namespace Nz } /*! - * \class Nz::TaskScheduler + * \ingroup core + * \class Nz::TaskScheduler * \brief Core class that represents a pool of threads * * \remark Initialized should be called first diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index da01025d3..0c4cd8008 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -22,7 +22,8 @@ namespace Nz { /*! - * \class Nz::Thread + * \ingroup core + * \class Nz::Thread * \brief Core class that represents a thread */ diff --git a/src/Nazara/Core/Unicode.cpp b/src/Nazara/Core/Unicode.cpp index 9168e855e..0f6dd8452 100644 --- a/src/Nazara/Core/Unicode.cpp +++ b/src/Nazara/Core/Unicode.cpp @@ -26,6 +26,7 @@ namespace Nz namespace Nz { /*! + * \ingroup core * \class Nz::Unicode * \brief Core class that represents a Unicode character */ From ad55ff159bcbae13414ff15fe6415ca96f86469e Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Mar 2016 15:38:04 +0100 Subject: [PATCH 145/229] Network: Add NetPacket to global header Former-commit-id: 51a55af65b954314b58ee7e80d26c0c97854f80c --- include/Nazara/Network.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Network.hpp b/include/Nazara/Network.hpp index d5c731be7..72565a17f 100644 --- a/include/Nazara/Network.hpp +++ b/include/Nazara/Network.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 09 Nov 2015 at 13:52:47 +// This file was automatically generated on 03 Feb 2016 at 00:06:56 /* Nazara Engine - Network module @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include From 192fccc634e4a11f33c568b6495e9535617e8f72 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 2 Mar 2016 16:53:20 +0100 Subject: [PATCH 146/229] Fix compilation Former-commit-id: d5ac6bb73615f7c9b068c1de2037dfeddc5c1b45 --- include/Nazara/Core/Bitset.inl | 2 +- include/Nazara/Core/SparsePtr.inl | 2 +- include/Nazara/Math/Matrix4.inl | 2 +- include/Nazara/Math/Vector2.inl | 2 +- include/Nazara/Math/Vector3.inl | 2 +- include/Nazara/Math/Vector4.inl | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 70c1158eb..bf89628f6 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -913,7 +913,7 @@ namespace Nz template template - void* Bitset::Bit::operator&() const + void* Bitset::Bit::operator&() const { // The template is necessary to make it fail only when used static_assert(!BadCall, "It is impossible to take the address of a bit in a bitset"); diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index d81c1eac3..166efe751 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -215,7 +215,7 @@ namespace Nz */ template - T* SparsePtr::operator->() const + T* SparsePtr::operator->() const { return reinterpret_cast(m_ptr); } diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 935387eba..6d84c241e 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -1786,7 +1786,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix) */ template -Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) +Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) { return matrix * scale; } diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 45e8d8f5d..6fd58cf38 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -989,7 +989,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec) */ template -Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) +Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) { return Nz::Vector2(scale * vec.x, scale * vec.y); } diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index f25fc5ba4..c386f146d 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -1300,7 +1300,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec) */ template -Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) +Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) { return Nz::Vector3(scale * vec.x, scale * vec.y, scale * vec.z); } diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index bdf2bd64f..01c771f8f 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -1038,7 +1038,7 @@ std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec) template -Nz::Vector4 operator*(T scale, const Nz::Vector4& vec) +Nz::Vector4 operator*(T scale, const Nz::Vector4& vec) { return Nz::Vector4(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w); } From d6a436100cd74e7a7b567a242ee84852d0faa552 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 2 Mar 2016 16:53:58 +0100 Subject: [PATCH 147/229] Network/IpAddress: Add std::hash specialization Former-commit-id: c8617065e51b307b541e4e58e3fb2494b144e828 --- include/Nazara/Network/IpAddress.inl | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index 425fa6fee..c11c1879a 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include @@ -211,4 +212,42 @@ namespace Nz } } +namespace std +{ + template<> + struct hash + { + size_t operator()(const Nz::IpAddress& ip) const + { + if (!ip) + return std::numeric_limits::max(); //< Returns a fixed value for invalid addresses + + // This is SDBM adapted for IP addresses, tested to generate the least collisions possible + // (It doesn't mean it cannot be improved though) + std::size_t hash = 0; + switch (ip.GetProtocol()) + { + case Nz::NetProtocol_Any: + case Nz::NetProtocol_Unknown: + return std::numeric_limits::max(); + + case Nz::NetProtocol_IPv4: + { + hash = ip.ToUInt32() + (hash << 6) + (hash << 16) - hash; + break; + } + case Nz::NetProtocol_IPv6: + { + Nz::IpAddress::IPv6 v6 = ip.ToIPv6(); + for (std::size_t i = 0; i < v6.size(); i++) + hash = v6[i] + (hash << 6) + (hash << 16) - hash; + + break; + } + } + + return ip.GetPort() + (hash << 6) + (hash << 16) - hash; + } + }; +} #include From 946d2cea7a585142e7c42d8deb496ed006597b1b Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 3 Mar 2016 14:10:52 +0100 Subject: [PATCH 148/229] SDK: Add global headers (improved global headers script) Former-commit-id: f04a3526b185c6c5b8025168cd56829898082bc6 --- SDK/include/NDK/Components.hpp | 17 +++++ SDK/include/NDK/Systems.hpp | 13 ++++ build/scripts/actions/generateheaders.lua | 77 +++++++++++++++++------ 3 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 SDK/include/NDK/Components.hpp create mode 100644 SDK/include/NDK/Systems.hpp diff --git a/SDK/include/NDK/Components.hpp b/SDK/include/NDK/Components.hpp new file mode 100644 index 000000000..a6d41e543 --- /dev/null +++ b/SDK/include/NDK/Components.hpp @@ -0,0 +1,17 @@ +// This file was automatically generated on 03 Mar 2016 at 14:09:12 + +#pragma once + +#ifndef NDK_COMPONENTS_GLOBAL_HPP +#define NDK_COMPONENTS_GLOBAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // NDK_COMPONENTS_GLOBAL_HPP diff --git a/SDK/include/NDK/Systems.hpp b/SDK/include/NDK/Systems.hpp new file mode 100644 index 000000000..d9bd12c75 --- /dev/null +++ b/SDK/include/NDK/Systems.hpp @@ -0,0 +1,13 @@ +// This file was automatically generated on 03 Mar 2016 at 14:09:12 + +#pragma once + +#ifndef NDK_SYSTEMS_GLOBAL_HPP +#define NDK_SYSTEMS_GLOBAL_HPP + +#include +#include +#include +#include + +#endif // NDK_SYSTEMS_GLOBAL_HPP diff --git a/build/scripts/actions/generateheaders.lua b/build/scripts/actions/generateheaders.lua index 01cea67e8..943919a90 100644 --- a/build/scripts/actions/generateheaders.lua +++ b/build/scripts/actions/generateheaders.lua @@ -1,11 +1,20 @@ ACTION.Name = "GenerateHeaders" ACTION.Description = "Generate a global header for each module" +ACTION.ModuleExcludes = {} +ACTION.ModuleExcludes["ConfigCheck.hpp"] = true +ACTION.ModuleExcludes["Debug.hpp"] = true +ACTION.ModuleExcludes["DebugOff.hpp"] = true +ACTION.ModuleExcludes["ThreadSafety.hpp"] = true +ACTION.ModuleExcludes["ThreadSafetyOff.hpp"] = true + +local action = ACTION ACTION.Function = function () + local paths = {} + local modules = os.matchdirs("../include/Nazara/*") for k, modulePath in pairs(modules) do local moduleName = modulePath:match(".*/(.*)") - print(moduleName) local config, err = io.open(modulePath .. "/Config.hpp", "r") local head = "" @@ -14,44 +23,72 @@ ACTION.Function = function () end for line in config:lines() do - head = head .. line .. "\n" - if (line == "#pragma once") then -- On s'arrête au #pragma once, qu'on inclut quand même + if (line == "#pragma once") then -- Stop before including the #pragma once as it's already written automatically break end + head = head .. line .. "\n" end config:close() - local header, err = io.open(modulePath .. ".hpp", "w+") + table.insert(paths, { + Excludes = action.ModuleExcludes, + Header = head, + HeaderGuard = "NAZARA_GLOBAL_" .. moduleName:upper() .. "_HPP", + Name = "Nazara" .. moduleName, + SearchDir = modulePath, + Target = modulePath .. ".hpp", + TopDir = "Nazara" + }) + end + + table.insert(paths, { + Excludes = {}, + HeaderGuard = "NDK_COMPONENTS_GLOBAL_HPP", + Name = "NDK Components", + SearchDir = "../SDK/include/NDK/Components", + TopDir = "NDK", + Target = "../SDK/include/NDK/Components.hpp" + }) + + table.insert(paths, { + Excludes = {}, + HeaderGuard = "NDK_SYSTEMS_GLOBAL_HPP", + Name = "NDK Systems", + SearchDir = "../SDK/include/NDK/Systems", + TopDir = "NDK", + Target = "../SDK/include/NDK/Systems.hpp" + }) + + for k,v in ipairs(paths) do + print(v.Name) + local header, err = io.open(v.Target, "w+") if (not header) then - error("Failed to create header file: " .. err) + error("Failed to create header file (" .. v.Target .. "): " .. err) end header:write("// This file was automatically generated on " .. os.date("%d %b %Y at %X") .. "\n\n") - header:write(head .. "\n") + if (v.Header) then + header:write(v.Header) + end - -- Protection du multi-including - local preprocessorName = "NAZARA_GLOBAL_" .. string.upper(moduleName) .. "_HPP" - header:write("#ifndef " .. preprocessorName .. "\n") - header:write("#define " .. preprocessorName .. "\n\n") + header:write("#pragma once\n\n") + header:write("#ifndef " .. v.HeaderGuard .. "\n") + header:write("#define " .. v.HeaderGuard .. "\n\n") - local files = os.matchfiles(modulePath .. "/*.hpp") + local files = os.matchfiles(v.SearchDir .. "/*.hpp") local count = 0 for k, filePath in pairs(files) do - local include, fileName = filePath:match(".*(Nazara/.*/(.*))") - if (fileName ~= "ConfigCheck.hpp" and - fileName ~= "Debug.hpp" and - fileName ~= "DebugOff.hpp" and - fileName ~= "ThreadSafety.hpp" and - fileName ~= "ThreadSafetyOff.hpp") then + local include, fileName = filePath:match(".*(" .. v.TopDir .. "/.*/(.*))") + if (not v.Excludes[fileName]) then header:write("#include <" .. include .. ">\n") count = count + 1 end end - - header:write("\n#endif // " .. preprocessorName .. "\n") + + header:write("\n#endif // " .. v.HeaderGuard .. "\n") header:close() - + print(string.format("-#include count: %d", count)) end end From e9d126b3a4e9ba96984e7ce4f1f6538b1610f341 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 6 Mar 2016 01:54:13 +0100 Subject: [PATCH 149/229] Math: Add serialization specialization for all types Former-commit-id: 7e45c50d3b4eabfc581736f290fc208592d3d46c --- include/Nazara/Math/BoundingVolume.hpp | 4 + include/Nazara/Math/BoundingVolume.inl | 54 +++++++++++ include/Nazara/Math/Box.hpp | 4 + include/Nazara/Math/Box.inl | 62 +++++++++++++ include/Nazara/Math/EulerAngles.hpp | 4 + include/Nazara/Math/EulerAngles.inl | 44 +++++++++ include/Nazara/Math/Frustum.hpp | 4 + include/Nazara/Math/Frustum.inl | 50 ++++++++++ include/Nazara/Math/Matrix4.hpp | 4 + include/Nazara/Math/Matrix4.inl | 38 ++++++++ include/Nazara/Math/OrientedBox.hpp | 4 + include/Nazara/Math/OrientedBox.inl | 36 ++++++++ include/Nazara/Math/Plane.hpp | 4 + include/Nazara/Math/Plane.inl | 38 ++++++++ include/Nazara/Math/Quaternion.hpp | 4 + include/Nazara/Math/Quaternion.inl | 51 +++++++++++ include/Nazara/Math/Ray.hpp | 4 + include/Nazara/Math/Ray.inl | 38 ++++++++ include/Nazara/Math/Rect.hpp | 4 + include/Nazara/Math/Rect.inl | 50 ++++++++++ include/Nazara/Math/Sphere.hpp | 4 + include/Nazara/Math/Sphere.inl | 50 ++++++++++ include/Nazara/Math/Vector2.hpp | 4 + include/Nazara/Math/Vector2.inl | 40 +++++++- include/Nazara/Math/Vector3.hpp | 4 + include/Nazara/Math/Vector3.inl | 122 +++++++++---------------- include/Nazara/Math/Vector4.hpp | 4 + include/Nazara/Math/Vector4.inl | 50 ++++++++++ 28 files changed, 699 insertions(+), 80 deletions(-) diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index e0ca2f556..b074b4a72 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -5,6 +5,7 @@ #ifndef NAZARA_BOUNDINGVOLUME_HPP #define NAZARA_BOUNDINGVOLUME_HPP +#include #include #include #include @@ -66,6 +67,9 @@ namespace Nz typedef BoundingVolume BoundingVolumed; typedef BoundingVolume BoundingVolumef; + + template bool Serialize(SerializationContext& context, const BoundingVolume& boundingVolume); + template bool Unserialize(SerializationContext& context, BoundingVolume* boundingVolume); } template diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 4047769dc..b5743b058 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -545,6 +545,60 @@ namespace Nz return volume; } + + /*! + * \brief Serializes a BoundingVolume + * \return true if successfully serialized + * + * \param context Serialization context + * \param boundingVolume Input bounding volume + * + * \remark Does not save OBB corners + */ + template + bool Serialize(SerializationContext& context, const BoundingVolume& boundingVolume) + { + if (!Serialize(context, static_cast(boundingVolume.extend))) + return false; + + if (!Serialize(context, boundingVolume.aabb)) + return false; + + if (!Serialize(context, boundingVolume.obb)) + return false; + + return true; + } + + /*! + * \brief Unserializes a BoundingVolume + * \return true if successfully unserialized + * + * \param context Serialization context + * \param boundingVolume Output bounding volume + * + * \remark The resulting oriented box corners will *not* be updated, a call to Update is required + */ + template + bool Unserialize(SerializationContext& context, BoundingVolume* boundingVolume) + { + UInt8 extend; + if (!Unserialize(context, &extend)) + return false; + + if (extend > Extend_Max) + return false; + + boundingVolume->extend = extend; + + if (!Unserialize(context, &boundingVolume->aabb)) + return false; + + if (!Unserialize(context, &boundingVolume->obb)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index d8de5bdab..a7bf6523e 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_BOX_HPP #define NAZARA_BOX_HPP +#include #include #include #include @@ -96,6 +97,9 @@ namespace Nz typedef Box Boxui; typedef Box Boxi32; typedef Box Boxui32; + + template bool Serialize(SerializationContext& context, const Box& box); + template bool Unserialize(SerializationContext& context, Box* box); } template diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 8c8d655ef..2c8b0e5d5 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -920,6 +920,68 @@ namespace Nz return box; } + + /*! + * \brief Serializes a Box + * \return true if successfully serialized + * + * \param context Serialization context + * \param box Input Box + */ + template + bool Serialize(SerializationContext& context, const Box& box) + { + if (!Serialize(context, box.x)) + return false; + + if (!Serialize(context, box.y)) + return false; + + if (!Serialize(context, box.z)) + return false; + + if (!Serialize(context, box.width)) + return false; + + if (!Serialize(context, box.height)) + return false; + + if (!Serialize(context, box.depth)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Box + * \return true if successfully unserialized + * + * \param context Serialization context + * \param box Output Box + */ + template + bool Unserialize(SerializationContext& context, Box* box) + { + if (!Unserialize(context, &box->x)) + return false; + + if (!Unserialize(context, &box->y)) + return false; + + if (!Unserialize(context, &box->z)) + return false; + + if (!Unserialize(context, &box->width)) + return false; + + if (!Unserialize(context, &box->height)) + return false; + + if (!Unserialize(context, &box->depth)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index 3c9a6b684..544ebff5a 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_EULERANGLES_HPP #define NAZARA_EULERANGLES_HPP +#include #include #include #include @@ -61,6 +62,9 @@ namespace Nz typedef EulerAngles EulerAnglesd; typedef EulerAngles EulerAnglesf; + + template bool Serialize(SerializationContext& context, const EulerAngles& eulerAngles); + template bool Unserialize(SerializationContext& context, EulerAngles* eulerAngles); } template std::ostream& operator<<(std::ostream& out, const Nz::EulerAngles& angles); diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index 5c442f6c9..8b4011e80 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -330,6 +330,50 @@ namespace Nz return angles; } + + /*! + * \brief Serializes a EulerAngles + * \return true if successfully serialized + * + * \param context Serialization context + * \param angles Input euler angles + */ + template + bool Serialize(SerializationContext& context, const EulerAngles& angles) + { + if (!Serialize(context, angles.pitch)) + return false; + + if (!Serialize(context, angles.yaw)) + return false; + + if (!Serialize(context, angles.roll)) + return false; + + return true; + } + + /*! + * \brief Unserializes a EulerAngles + * \return true if successfully unserialized + * + * \param context Serialization context + * \param angles Output euler angles + */ + template + bool Unserialize(SerializationContext& context, EulerAngles* angles) + { + if (!Unserialize(context, &angles->pitch)) + return false; + + if (!Unserialize(context, &angles->yaw)) + return false; + + if (!Unserialize(context, &angles->roll)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index 44c3bc0e7..ab0447351 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_FRUSTUM_HPP #define NAZARA_FRUSTUM_HPP +#include #include #include #include @@ -60,6 +61,9 @@ namespace Nz typedef Frustum Frustumd; typedef Frustum Frustumf; + + template bool Serialize(SerializationContext& context, const Frustum& frustum); + template bool Unserialize(SerializationContext& context, Frustum* frustum); } template diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 4ff2b8f1b..6889f92f4 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -674,6 +674,56 @@ namespace Nz << " Right: " << m_planes[FrustumPlane_Right].ToString() << "\n" << " Top: " << m_planes[FrustumPlane_Top].ToString() << ")\n"; } + + /*! + * \brief Serializes a Frustum + * \return true if successfully serialized + * + * \param context Serialization context + * \param matrix Input frustum + */ + template + bool Serialize(SerializationContext& context, const Frustum& frustum) + { + for (unsigned int i = 0; i <= BoxCorner_Max; ++i) + { + if (!Serialize(context, m_corners[i])) + return false; + } + + for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) + { + if (!Serialize(context, m_planes[i])) + return false; + } + + return true; + } + + /*! + * \brief Unserializes a Matrix4 + * \return true if successfully unserialized + * + * \param context Serialization context + * \param matrix Output matrix + */ + template + bool Unserialize(SerializationContext& context, Frustum* frustum) + { + for (unsigned int i = 0; i <= BoxCorner_Max; ++i) + { + if (!Unserialize(context, &m_corners[i])) + return false; + } + + for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) + { + if (!Unserialize(context, &m_planes[i])) + return false; + } + + return true; + } } /*! diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 211e8eedb..687eb4e0d 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -9,6 +9,7 @@ ///FIXME: Matrices column-major, difficile de bosser avec (Tout passer en row-major et transposer dans les shaders ?) +#include #include #include @@ -138,6 +139,9 @@ namespace Nz typedef Matrix4 Matrix4d; typedef Matrix4 Matrix4f; + + template bool Serialize(SerializationContext& context, const Matrix4& matrix); + template bool Unserialize(SerializationContext& context, Matrix4* matrix); } template std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix); diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 6d84c241e..161ba96ad 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -1761,6 +1761,44 @@ namespace Nz return matrix; } + + /*! + * \brief Serializes a Matrix4 + * \return true if successfully serialized + * + * \param context Serialization context + * \param matrix Input matrix + */ + template + bool Serialize(SerializationContext& context, const Matrix4& matrix) + { + for (unsigned int i = 0; i < 16; ++i) + { + if (!Serialize(context, matrix[i])) + return false; + } + + return true; + } + + /*! + * \brief Unserializes a Matrix4 + * \return true if successfully unserialized + * + * \param context Serialization context + * \param matrix Output matrix + */ + template + bool Unserialize(SerializationContext& context, Matrix4* matrix) + { + for (unsigned int i = 0; i < 16; ++i) + { + if (!Unserialize(context, &matrix[i])) + return false; + } + + return true; + } } /*! diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 627f4cbe9..6ec640de2 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_ORIENTEDBOX_HPP #define NAZARA_ORIENTEDBOX_HPP +#include #include #include #include @@ -67,6 +68,9 @@ namespace Nz typedef OrientedBox OrientedBoxd; typedef OrientedBox OrientedBoxf; + + template bool Serialize(SerializationContext& context, const OrientedBox& obb); + template bool Unserialize(SerializationContext& context, OrientedBox* obb); } template diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index 188b6d8fc..e6f42b286 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -430,6 +430,42 @@ namespace Nz return orientedBox; } + + /*! + * \brief Serializes a OrientedBox + * \return true if successfully serialized + * + * \param context Serialization context + * \param obb Input oriented box + * + * \remark Does not save OBB corners + */ + template + bool Serialize(SerializationContext& context, const OrientedBox& obb) + { + if (!Serialize(context, obb.localBox)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Matrix4 + * \return true if successfully unserialized + * + * \param context Serialization context + * \param obb Output oriented box + * + * \remark The resulting oriented box corners will *not* be updated, a call to Update is required + */ + template + bool Unserialize(SerializationContext& context, OrientedBox* obb) + { + if (!Unserialize(context, &obb->localBox)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index 70bc06051..fbc1a3f12 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_PLANE_HPP #define NAZARA_PLANE_HPP +#include #include #include @@ -57,6 +58,9 @@ namespace Nz typedef Plane Planed; typedef Plane Planef; + + template bool Serialize(SerializationContext& context, const Plane& plane); + template bool Unserialize(SerializationContext& context, Plane* plane); } template diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 29bd829b2..6dccba3d7 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -424,6 +424,44 @@ namespace Nz return plane; } + + /*! + * \brief Serializes a Vector2 + * \return true if successfully serialized + * + * \param context Serialization context + * \param plane Input Vector2 + */ + template + bool Serialize(SerializationContext& context, const Plane& plane) + { + if (!Serialize(context, plane.normal)) + return false; + + if (!Serialize(context, plane.distance)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Plane + * \return true if successfully unserialized + * + * \param context Serialization context + * \param plane Output Plane + */ + template + bool Unserialize(SerializationContext& context, Plane* plane) + { + if (!Unserialize(context, &plane->normal)) + return false; + + if (!Unserialize(context, &plane->distance)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index f33dec0b6..b984cea69 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_QUATERNION_HPP #define NAZARA_QUATERNION_HPP +#include #include namespace Nz @@ -88,6 +89,9 @@ namespace Nz typedef Quaternion Quaterniond; typedef Quaternion Quaternionf; + + template bool Serialize(SerializationContext& context, const Quaternion& quat); + template bool Unserialize(SerializationContext& context, Quaternion* quat); } template std::ostream& operator<<(std::ostream& out, const Nz::Quaternion& quat); diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 75e3966d3..012c3578a 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -831,6 +831,57 @@ namespace Nz return quaternion; } + + + /*! + * \brief Serializes a Quaternion + * \return true if successfully serialized + * + * \param context Serialization context + * \param quat Input Quaternion + */ + template + bool Serialize(SerializationContext& context, const Quaternion& quat) + { + if (!Serialize(context, quat.x)) + return false; + + if (!Serialize(context, quat.y)) + return false; + + if (!Serialize(context, quat.z)) + return false; + + if (!Serialize(context, quat.w)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Quaternion + * \return true if successfully unserialized + * + * \param context Serialization context + * \param quat Output Quaternion + */ + template + bool Unserialize(SerializationContext& context, Quaternion* quat) + { + if (!Unserialize(context, &quat->x)) + return false; + + if (!Unserialize(context, &quat->y)) + return false; + + if (!Unserialize(context, &quat->z)) + return false; + + if (!Unserialize(context, &quat->w)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index c4c53664d..22c520dfc 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_RAY_HPP #define NAZARA_RAY_HPP +#include #include #include #include @@ -73,6 +74,9 @@ namespace Nz typedef Ray Rayd; typedef Ray Rayf; + + template bool Serialize(SerializationContext& context, const Ray& ray); + template bool Unserialize(SerializationContext& context, Ray* ray); } template std::ostream& operator<<(std::ostream& out, const Nz::Ray& vec); diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index e83c39488..c601f018b 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -762,6 +762,44 @@ namespace Nz { return Ray(Nz::Vector3::Lerp(from.origin, to.origin, interpolation), Nz::Vector3::Lerp(from.direction, to.direction, interpolation)); } + + /*! + * \brief Serializes a Ray + * \return true if successfully serialized + * + * \param context Serialization context + * \param ray Input Ray + */ + template + bool Serialize(SerializationContext& context, const Ray& ray) + { + if (!Serialize(context, ray.origin)) + return false; + + if (!Serialize(context, ray.direction)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Ray + * \return true if successfully unserialized + * + * \param context Serialization context + * \param ray Output Ray + */ + template + bool Unserialize(SerializationContext& context, Ray* ray) + { + if (!Unserialize(context, &ray->origin)) + return false; + + if (!Unserialize(context, &ray->direction)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index ec203848f..f51e88c8a 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_RECT_HPP #define NAZARA_RECT_HPP +#include #include #include #include @@ -90,6 +91,9 @@ namespace Nz typedef Rect Rectui; typedef Rect Recti32; typedef Rect Rectui32; + + template bool Serialize(SerializationContext& context, const Rect& rect); + template bool Unserialize(SerializationContext& context, Rect* rect); } template diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 9a2737a02..2f72b30ec 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -816,6 +816,56 @@ namespace Nz return rect; } + + /*! + * \brief Serializes a Rect + * \return true if successfully serialized + * + * \param context Serialization context + * \param rect Input Rect + */ + template + bool Serialize(SerializationContext& context, const Rect& rect) + { + if (!Serialize(context, rect.x)) + return false; + + if (!Serialize(context, rect.y)) + return false; + + if (!Serialize(context, rect.width)) + return false; + + if (!Serialize(context, rect.height)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Rect + * \return true if successfully unserialized + * + * \param context Serialization context + * \param rect Output Rect + */ + template + bool Unserialize(SerializationContext& context, Rect* rect) + { + if (!Unserialize(context, &rect->x)) + return false; + + if (!Unserialize(context, &rect->y)) + return false; + + if (!Unserialize(context, &rect->width)) + return false; + + if (!Unserialize(context, &rect->height)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 65203c4b0..e2d766744 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_SPHERE_HPP #define NAZARA_SPHERE_HPP +#include #include #include @@ -80,6 +81,9 @@ namespace Nz typedef Sphere Sphered; typedef Sphere Spheref; + + template bool Serialize(SerializationContext& context, const Sphere& sphere); + template bool Unserialize(SerializationContext& context, Sphere* sphere); } template diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index eac46d76c..4dca542fb 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -674,6 +674,56 @@ namespace Nz return sphere; } + + /*! + * \brief Serializes a Sphere + * \return true if successfully serialized + * + * \param context Serialization context + * \param sphere Input Sphere + */ + template + bool Serialize(SerializationContext& context, const Sphere& sphere) + { + if (!Serialize(context, sphere.x)) + return false; + + if (!Serialize(context, sphere.y)) + return false; + + if (!Serialize(context, sphere.z)) + return false; + + if (!Serialize(context, sphere.radius)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Sphere + * \return true if successfully unserialized + * + * \param context Serialization context + * \param sphere Output Sphere + */ + template + bool Unserialize(SerializationContext& context, Sphere* sphere) + { + if (!Unserialize(context, &sphere->x)) + return false; + + if (!Unserialize(context, &sphere->y)) + return false; + + if (!Unserialize(context, &sphere->z)) + return false; + + if (!Unserialize(context, &sphere->radius)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 3712f0d09..d96420a67 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_VECTOR2_HPP #define NAZARA_VECTOR2_HPP +#include #include namespace Nz @@ -106,6 +107,9 @@ namespace Nz typedef Vector2 Vector2ui; typedef Vector2 Vector2i32; typedef Vector2 Vector2ui32; + + template bool Serialize(SerializationContext& context, const Vector2& vector); + template bool Unserialize(SerializationContext& context, Vector2* vector); } template std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec); diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 6fd58cf38..6ee7af3e0 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -940,7 +940,6 @@ namespace Nz * * \see MakeUnitY */ - template Vector2 Vector2::UnitY() { @@ -956,7 +955,6 @@ namespace Nz * * \see MakeZero */ - template Vector2 Vector2::Zero() { @@ -965,6 +963,44 @@ namespace Nz return vector; } + + /*! + * \brief Serializes a Vector2 + * \return true if successfully serialized + * + * \param context Serialization context + * \param vector Input Vector2 + */ + template + bool Serialize(SerializationContext& context, const Vector2& vector) + { + if (!Serialize(context, vector.x)) + return false; + + if (!Serialize(context, vector.y)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Vector2 + * \return true if successfully unserialized + * + * \param context Serialization context + * \param vector Output Vector2 + */ + template + bool Unserialize(SerializationContext& context, Vector2* vector) + { + if (!Unserialize(context, &vector->x)) + return false; + + if (!Unserialize(context, &vector->y)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 0ab620406..c14ab503a 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_VECTOR3_HPP #define NAZARA_VECTOR3_HPP +#include #include namespace Nz @@ -125,6 +126,9 @@ namespace Nz typedef Vector3 Vector3ui; typedef Vector3 Vector3i32; typedef Vector3 Vector3ui32; + + template bool Serialize(SerializationContext& context, const Vector3& vector); + template bool Unserialize(SerializationContext& context, Vector3* vector); } template std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec); diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index c386f146d..b6159d867 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -28,7 +28,6 @@ namespace Nz * \param Y Y component * \param Z Z component */ - template Vector3::Vector3(T X, T Y, T Z) { @@ -41,7 +40,6 @@ namespace Nz * \param X X component * \param vec vec.X = Y component and vec.y = Z component */ - template Vector3::Vector3(T X, const Vector2& vec) { @@ -53,7 +51,6 @@ namespace Nz * * \param scale X component = Y component = Z component */ - template Vector3::Vector3(T scale) { @@ -65,7 +62,6 @@ namespace Nz * * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component */ - template Vector3::Vector3(const T vec[3]) { @@ -78,7 +74,6 @@ namespace Nz * \param vec vec.X = X component and vec.y = Y component * \param Z Z component */ - template Vector3::Vector3(const Vector2& vec, T Z) { @@ -90,7 +85,6 @@ namespace Nz * * \param vec Vector of type U to convert to type T */ - template template Vector3::Vector3(const Vector3& vec) @@ -103,7 +97,6 @@ namespace Nz * * \param vec Vector4 where only the first three components are taken */ - template Vector3::Vector3(const Vector4& vec) { @@ -118,7 +111,6 @@ namespace Nz * * \see DotProduct */ - template T Vector3::AbsDotProduct(const Vector3& vec) const { @@ -137,7 +129,6 @@ namespace Nz * * \see NormalizeAngle */ - template T Vector3::AngleBetween(const Vector3& vec) const { @@ -166,7 +157,6 @@ namespace Nz * * \see CrossProduct */ - template Vector3 Vector3::CrossProduct(const Vector3& vec) const { @@ -181,7 +171,6 @@ namespace Nz * * \see SquaredDistance */ - template T Vector3::Distance(const Vector3& vec) const { @@ -194,7 +183,6 @@ namespace Nz * * \param vec The other vector to measure the distance with */ - template float Vector3::Distancef(const Vector3& vec) const { @@ -209,7 +197,6 @@ namespace Nz * * \see AbsDotProduct, DotProduct */ - template T Vector3::DotProduct(const Vector3& vec) const { @@ -222,7 +209,6 @@ namespace Nz * * \see GetSquaredLength */ - template T Vector3::GetLength() const { @@ -233,7 +219,6 @@ namespace Nz * \brief Calculates the length (magnitude) of the vector * \return The length in float of the vector */ - template float Vector3::GetLengthf() const { @@ -250,7 +235,6 @@ namespace Nz * * \see Normalize */ - template Vector3 Vector3::GetNormal(T* length) const { @@ -266,7 +250,6 @@ namespace Nz * * \see GetLength */ - template T Vector3::GetSquaredLength() const { @@ -279,7 +262,6 @@ namespace Nz * * \see Backward */ - template Vector3& Vector3::MakeBackward() { @@ -292,7 +274,6 @@ namespace Nz * * \see Down */ - template Vector3& Vector3::MakeDown() { @@ -305,7 +286,6 @@ namespace Nz * * \see Forward */ - template Vector3& Vector3::MakeForward() { @@ -318,7 +298,6 @@ namespace Nz * * \see Left */ - template Vector3& Vector3::MakeLeft() { @@ -331,7 +310,6 @@ namespace Nz * * \see Right */ - template Vector3& Vector3::MakeRight() { @@ -344,7 +322,6 @@ namespace Nz * * \see Unit */ - template Vector3& Vector3::MakeUnit() { @@ -357,7 +334,6 @@ namespace Nz * * \see UnitX */ - template Vector3& Vector3::MakeUnitX() { @@ -370,7 +346,6 @@ namespace Nz * * \see UnitY */ - template Vector3& Vector3::MakeUnitY() { @@ -383,7 +358,6 @@ namespace Nz * * \see UnitZ */ - template Vector3& Vector3::MakeUnitZ() { @@ -396,7 +370,6 @@ namespace Nz * * \see Up */ - template Vector3& Vector3::MakeUp() { @@ -409,7 +382,6 @@ namespace Nz * * \see Zero */ - template Vector3& Vector3::MakeZero() { @@ -424,7 +396,6 @@ namespace Nz * * \see Minimize */ - template Vector3& Vector3::Maximize(const Vector3& vec) { @@ -448,7 +419,6 @@ namespace Nz * * \see Maximize */ - template Vector3& Vector3::Minimize(const Vector3& vec) { @@ -474,7 +444,6 @@ namespace Nz * * \see GetNormal */ - template Vector3& Vector3::Normalize(T* length) { @@ -501,7 +470,6 @@ namespace Nz * \param Y Y component * \param Z Z component */ - template Vector3& Vector3::Set(T X, T Y, T Z) { @@ -518,7 +486,6 @@ namespace Nz * \param X X component * \param vec vec.X = Y component and vec.y = Z component */ - template Vector3& Vector3::Set(T X, const Vector2& vec) { @@ -535,7 +502,6 @@ namespace Nz * * \param scale X component = Y component = Z component */ - template Vector3& Vector3::Set(T scale) { @@ -552,7 +518,6 @@ namespace Nz * * \param vec[3] vec[0] is X component, vec[1] is Y component and vec[2] is Z component */ - template Vector3& Vector3::Set(const T vec[3]) { @@ -567,7 +532,6 @@ namespace Nz * \param vec vec.X = X component and vec.y = Y component * \param Z Z component */ - template Vector3& Vector3::Set(const Vector2& vec, T Z) { @@ -584,7 +548,6 @@ namespace Nz * * \param vec The other vector */ - template Vector3& Vector3::Set(const Vector3& vec) { @@ -599,7 +562,6 @@ namespace Nz * * \param vec Vector of type U to convert its components */ - template template Vector3& Vector3::Set(const Vector3& vec) @@ -617,7 +579,6 @@ namespace Nz * * \param vec Vector4 where only the first three components are taken */ - template Vector3& Vector3::Set(const Vector4& vec) { @@ -636,7 +597,6 @@ namespace Nz * * \see Distance */ - template T Vector3::SquaredDistance(const Vector3& vec) const { @@ -647,7 +607,6 @@ namespace Nz * \brief Gives a string representation * \return A string representation of the object: "Vector3(x, y, z)" */ - template String Vector3::ToString() const { @@ -662,7 +621,6 @@ namespace Nz * * \remark Access to index greather than 2 is undefined behavior */ - template Vector3::operator T* () { @@ -675,7 +633,6 @@ namespace Nz * * \remark Access to index greather than 2 is undefined behavior */ - template Vector3::operator const T* () const { @@ -686,7 +643,6 @@ namespace Nz * \brief Helps to represent the sign of the vector * \return A constant reference to this vector */ - template const Vector3& Vector3::operator+() const { @@ -697,7 +653,6 @@ namespace Nz * \brief Negates the components of the vector * \return A constant reference to this vector with negate components */ - template Vector3 Vector3::operator-() const { @@ -710,7 +665,6 @@ namespace Nz * * \param vec The other vector to add components with */ - template Vector3 Vector3::operator+(const Vector3& vec) const { @@ -723,7 +677,6 @@ namespace Nz * * \param vec The other vector to substract components with */ - template Vector3 Vector3::operator-(const Vector3& vec) const { @@ -736,7 +689,6 @@ namespace Nz * * \param vec The other vector to multiply components with */ - template Vector3 Vector3::operator*(const Vector3& vec) const { @@ -749,7 +701,6 @@ namespace Nz * * \param scale The scalar to multiply components with */ - template Vector3 Vector3::operator*(T scale) const { @@ -765,7 +716,6 @@ namespace Nz * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null */ - template Vector3 Vector3::operator/(const Vector3& vec) const { @@ -791,7 +741,6 @@ namespace Nz * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null */ - template Vector3 Vector3::operator/(T scale) const { @@ -814,7 +763,6 @@ namespace Nz * * \param vec The other vector to add components with */ - template Vector3& Vector3::operator+=(const Vector3& vec) { @@ -831,7 +779,6 @@ namespace Nz * * \param vec The other vector to substract components with */ - template Vector3& Vector3::operator-=(const Vector3& vec) { @@ -848,7 +795,6 @@ namespace Nz * * \param vec The other vector to multiply components with */ - template Vector3& Vector3::operator*=(const Vector3& vec) { @@ -865,7 +811,6 @@ namespace Nz * * \param vec The other vector to multiply components with */ - template Vector3& Vector3::operator*=(T scale) { @@ -885,7 +830,6 @@ namespace Nz * \remark Produce a NazaraError if one of the vec components is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and one of the vec components is null */ - template Vector3& Vector3::operator/=(const Vector3& vec) { @@ -913,7 +857,6 @@ namespace Nz * \remark Produce a NazaraError if scale is null with NAZARA_MATH_SAFE defined * \throw std::domain_error if NAZARA_MATH_SAFE is defined and scale is null */ - template Vector3& Vector3::operator/=(T scale) { @@ -938,7 +881,6 @@ namespace Nz * * \param vec Other vector to compare with */ - template bool Vector3::operator==(const Vector3& vec) const { @@ -953,7 +895,6 @@ namespace Nz * * \param vec Other vector to compare with */ - template bool Vector3::operator!=(const Vector3& vec) const { @@ -966,7 +907,6 @@ namespace Nz * * \param vec Other vector to compare with */ - template bool Vector3::operator<(const Vector3& vec) const { @@ -987,7 +927,6 @@ namespace Nz * * \param vec Other vector to compare with */ - template bool Vector3::operator<=(const Vector3& vec) const { @@ -1008,7 +947,6 @@ namespace Nz * * \param vec Other vector to compare with */ - template bool Vector3::operator>(const Vector3& vec) const { @@ -1021,7 +959,6 @@ namespace Nz * * \param vec Other vector to compare with */ - template bool Vector3::operator>=(const Vector3& vec) const { @@ -1037,7 +974,6 @@ namespace Nz * * \see CrossProduct */ - template Vector3 Vector3::CrossProduct(const Vector3& vec1, const Vector3& vec2) { @@ -1053,7 +989,6 @@ namespace Nz * * \see AbsDotProduct, DotProduct */ - template T Vector3::DotProduct(const Vector3& vec1, const Vector3& vec2) { @@ -1066,7 +1001,6 @@ namespace Nz * * \see MakeBackward */ - template Vector3 Vector3::Backward() { @@ -1082,7 +1016,6 @@ namespace Nz * * \see MakeDown */ - template Vector3 Vector3::Down() { @@ -1098,7 +1031,6 @@ namespace Nz * * \see Forward */ - template Vector3 Vector3::Forward() { @@ -1114,7 +1046,6 @@ namespace Nz * * \see MakeLeft */ - template Vector3 Vector3::Left() { @@ -1136,7 +1067,6 @@ namespace Nz * * \see Lerp */ - template Vector3 Vector3::Lerp(const Vector3& from, const Vector3& to, T interpolation) { @@ -1158,7 +1088,6 @@ namespace Nz * * \see GetNormal */ - template Vector3 Vector3::Normalize(const Vector3& vec) { @@ -1171,7 +1100,6 @@ namespace Nz * * \see MakeRight */ - template Vector3 Vector3::Right() { @@ -1187,7 +1115,6 @@ namespace Nz * * \see MakeUnit */ - template Vector3 Vector3::Unit() { @@ -1203,7 +1130,6 @@ namespace Nz * * \see MakeUnitX */ - template Vector3 Vector3::UnitX() { @@ -1219,7 +1145,6 @@ namespace Nz * * \see MakeUnitY */ - template Vector3 Vector3::UnitY() { @@ -1235,7 +1160,6 @@ namespace Nz * * \see MakeUnitZ */ - template Vector3 Vector3::UnitZ() { @@ -1251,7 +1175,6 @@ namespace Nz * * \see MakeUp */ - template Vector3 Vector3::Up() { @@ -1267,7 +1190,6 @@ namespace Nz * * \see MakeZero */ - template Vector3 Vector3::Zero() { @@ -1276,6 +1198,50 @@ namespace Nz return vector; } + + /*! + * \brief Serializes a Vector3 + * \return true if successfully serialized + * + * \param context Serialization context + * \param vector Input Vector3 + */ + template + bool Serialize(SerializationContext& context, const Vector3& vector) + { + if (!Serialize(context, vector.x)) + return false; + + if (!Serialize(context, vector.y)) + return false; + + if (!Serialize(context, vector.z)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Vector3 + * \return true if successfully unserialized + * + * \param context Serialization context + * \param vector Output Vector3 + */ + template + bool Unserialize(SerializationContext& context, Vector3* vector) + { + if (!Unserialize(context, &vector->x)) + return false; + + if (!Unserialize(context, &vector->y)) + return false; + + if (!Unserialize(context, &vector->z)) + return false; + + return true; + } } /*! diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index 319f18e3b..f8e6d6895 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_VECTOR4_HPP #define NAZARA_VECTOR4_HPP +#include #include namespace Nz @@ -104,6 +105,9 @@ namespace Nz typedef Vector4 Vector4ui; typedef Vector4 Vector4i32; typedef Vector4 Vector4ui32; + + template bool Serialize(SerializationContext& context, const Vector4& vector); + template bool Unserialize(SerializationContext& context, Vector4* vector); } template std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec); diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 01c771f8f..9c5fd92c7 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -1013,6 +1013,56 @@ namespace Nz return vector; } + + /*! + * \brief Serializes a Vector4 + * \return true if successfully serialized + * + * \param context Serialization context + * \param vector Input Vector3 + */ + template + bool Serialize(SerializationContext& context, const Vector4& vector) + { + if (!Serialize(context, vector.x)) + return false; + + if (!Serialize(context, vector.y)) + return false; + + if (!Serialize(context, vector.z)) + return false; + + if (!Serialize(context, vector.w)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Vector4 + * \return true if successfully unserialized + * + * \param context Serialization context + * \param vector Output Vector3 + */ + template + bool Unserialize(SerializationContext& context, Vector4* vector) + { + if (!Unserialize(context, &vector->x)) + return false; + + if (!Unserialize(context, &vector->y)) + return false; + + if (!Unserialize(context, &vector->z)) + return false; + + if (!Unserialize(context, &vector->w)) + return false; + + return true; + } } /*! From 300dc82806e24c5260d78253934f1ff9cd943d62 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 6 Mar 2016 14:54:56 +0100 Subject: [PATCH 150/229] Math: Fix missing includes Former-commit-id: 21ff7a6db4beb9fc7968e9bf1ba7478ca2f55e21 --- include/Nazara/Math/BoundingVolume.hpp | 3 ++- include/Nazara/Math/BoundingVolume.inl | 1 + include/Nazara/Math/Box.hpp | 3 ++- include/Nazara/Math/Box.inl | 1 + include/Nazara/Math/EulerAngles.hpp | 3 ++- include/Nazara/Math/EulerAngles.inl | 1 + include/Nazara/Math/Frustum.hpp | 3 ++- include/Nazara/Math/Frustum.inl | 1 + include/Nazara/Math/Matrix4.hpp | 3 ++- include/Nazara/Math/Matrix4.inl | 1 + include/Nazara/Math/OrientedBox.hpp | 3 ++- include/Nazara/Math/OrientedBox.inl | 1 + include/Nazara/Math/Plane.hpp | 3 ++- include/Nazara/Math/Plane.inl | 1 + include/Nazara/Math/Quaternion.hpp | 3 ++- include/Nazara/Math/Quaternion.inl | 1 + include/Nazara/Math/Ray.hpp | 3 ++- include/Nazara/Math/Ray.inl | 1 + include/Nazara/Math/Rect.hpp | 3 ++- include/Nazara/Math/Rect.inl | 1 + include/Nazara/Math/Sphere.hpp | 3 ++- include/Nazara/Math/Sphere.inl | 1 + include/Nazara/Math/Vector2.hpp | 3 ++- include/Nazara/Math/Vector2.inl | 1 + include/Nazara/Math/Vector3.hpp | 3 ++- include/Nazara/Math/Vector3.inl | 1 + include/Nazara/Math/Vector4.hpp | 3 ++- include/Nazara/Math/Vector4.inl | 1 + 28 files changed, 42 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index b074b4a72..60a16c260 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -5,7 +5,6 @@ #ifndef NAZARA_BOUNDINGVOLUME_HPP #define NAZARA_BOUNDINGVOLUME_HPP -#include #include #include #include @@ -15,6 +14,8 @@ namespace Nz { + struct SerializationContext; + template class BoundingVolume { diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index b5743b058..03e6476bc 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index a7bf6523e..a2a6f25d1 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -7,7 +7,6 @@ #ifndef NAZARA_BOX_HPP #define NAZARA_BOX_HPP -#include #include #include #include @@ -17,6 +16,8 @@ namespace Nz { + struct SerializationContext; + template class Box { diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 2c8b0e5d5..a6200cbe4 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index 544ebff5a..6ada39982 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -7,13 +7,14 @@ #ifndef NAZARA_EULERANGLES_HPP #define NAZARA_EULERANGLES_HPP -#include #include #include #include namespace Nz { + struct SerializationContext; + template class EulerAngles { diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index 8b4011e80..24bfd4630 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index ab0447351..e170c2e55 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -7,7 +7,6 @@ #ifndef NAZARA_FRUSTUM_HPP #define NAZARA_FRUSTUM_HPP -#include #include #include #include @@ -19,6 +18,8 @@ namespace Nz { + struct SerializationContext; + template class Frustum { diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 6889f92f4..2e78682d1 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -6,6 +6,7 @@ // http://www.crownandcutlass.com/features/technicaldetails/frustum.html // http://www.lighthouse3d.com/tutorials/view-frustum-culling/ +#include #include #include #include diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 687eb4e0d..91927d68a 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -9,12 +9,13 @@ ///FIXME: Matrices column-major, difficile de bosser avec (Tout passer en row-major et transposer dans les shaders ?) -#include #include #include namespace Nz { + struct SerializationContext; + template class EulerAngles; template class Quaternion; template class Vector2; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 161ba96ad..afa8143e3 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 6ec640de2..43d4b1aaf 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -7,7 +7,6 @@ #ifndef NAZARA_ORIENTEDBOX_HPP #define NAZARA_ORIENTEDBOX_HPP -#include #include #include #include @@ -15,6 +14,8 @@ namespace Nz { + struct SerializationContext; + template class OrientedBox { diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index e6f42b286..9bcd94e1d 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index fbc1a3f12..f37fc90c7 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -7,12 +7,13 @@ #ifndef NAZARA_PLANE_HPP #define NAZARA_PLANE_HPP -#include #include #include namespace Nz { + struct SerializationContext; + template class Plane { diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 6dccba3d7..625abe3e4 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index b984cea69..bbb313bd5 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -7,11 +7,12 @@ #ifndef NAZARA_QUATERNION_HPP #define NAZARA_QUATERNION_HPP -#include #include namespace Nz { + struct SerializationContext; + template class EulerAngles; template class Vector3; diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 012c3578a..bc672cd81 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index 22c520dfc..b391ad866 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -7,7 +7,6 @@ #ifndef NAZARA_RAY_HPP #define NAZARA_RAY_HPP -#include #include #include #include @@ -19,6 +18,8 @@ namespace Nz { + struct SerializationContext; + template class Ray { diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index c601f018b..6045615ed 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index f51e88c8a..393d8d116 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -7,13 +7,14 @@ #ifndef NAZARA_RECT_HPP #define NAZARA_RECT_HPP -#include #include #include #include namespace Nz { + struct SerializationContext; + template class Rect { diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 2f72b30ec..f53dd0c0f 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index e2d766744..929c1ec71 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -7,12 +7,13 @@ #ifndef NAZARA_SPHERE_HPP #define NAZARA_SPHERE_HPP -#include #include #include namespace Nz { + struct SerializationContext; + template class Box; template diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 4dca542fb..4d30c7ca3 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index d96420a67..b275d0544 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -7,11 +7,12 @@ #ifndef NAZARA_VECTOR2_HPP #define NAZARA_VECTOR2_HPP -#include #include namespace Nz { + struct SerializationContext; + template class Vector3; template class Vector4; diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 6ee7af3e0..80e588ba4 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index c14ab503a..b9d16011c 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -7,11 +7,12 @@ #ifndef NAZARA_VECTOR3_HPP #define NAZARA_VECTOR3_HPP -#include #include namespace Nz { + struct SerializationContext; + template class Vector2; template class Vector4; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index b6159d867..fa48b7bef 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index f8e6d6895..d1e51433a 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -7,11 +7,12 @@ #ifndef NAZARA_VECTOR4_HPP #define NAZARA_VECTOR4_HPP -#include #include namespace Nz { + struct SerializationContext; + template class Vector2; template class Vector3; diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 9c5fd92c7..73a9a0802 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include From a39cfcc92e486aa1aa1cd11d7fc25b7de23d5a71 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 6 Mar 2016 14:55:42 +0100 Subject: [PATCH 151/229] Core/Color: Add serialization Former-commit-id: ef50b4303a3fbc5e2b49ba440d9008fb6d51a7e3 --- include/Nazara/Core/Color.hpp | 5 ++++ include/Nazara/Core/Color.inl | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index a7df6b9a2..91a8cc43d 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -13,6 +13,8 @@ namespace Nz { + struct SerializationContext; + class Color { public: @@ -62,6 +64,9 @@ namespace Nz private: static float Hue2RGB(float v1, float v2, float vH); }; + + inline bool Serialize(SerializationContext& context, const Color& color); + inline bool Unserialize(SerializationContext& context, Color* color); } std::ostream& operator<<(std::ostream& out, const Nz::Color& color); diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index c3359cd0f..4ac3a2246 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include #include @@ -610,6 +611,54 @@ namespace Nz return v1; } + + /*! + * \brief Serializes a Color + * \return true if successfully serialized + * + * \param context Serialization context + * \param color Input color + */ + inline bool Serialize(SerializationContext& context, const Color& color) + { + if (!Serialize(context, color.r)) + return false; + + if (!Serialize(context, color.g)) + return false; + + if (!Serialize(context, color.b)) + return false; + + if (!Serialize(context, color.a)) + return false; + + return true; + } + + /*! + * \brief Unserializes a Color + * \return true if successfully unserialized + * + * \param context Serialization context + * \param color Output color + */ + inline bool Unserialize(SerializationContext& context, Color* color) + { + if (!Unserialize(context, &color->r)) + return false; + + if (!Unserialize(context, &color->g)) + return false; + + if (!Unserialize(context, &color->b)) + return false; + + if (!Unserialize(context, &color->a)) + return false; + + return true; + } } /*! From 883f2eca393e7d4ceeadf96f7009318f59a6cd8b Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 7 Mar 2016 13:05:21 +0100 Subject: [PATCH 152/229] Extlibs/STB: Update stb_image.h and add stb_image_write.h Former-commit-id: 1b567271240b0207780c2d516fad9e03575ce388 --- src/Nazara/Utility/Formats/STBLoader.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 75d185e82..ef1a815b4 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include @@ -17,6 +17,12 @@ namespace Nz { namespace { + int Eof(void* userdata) + { + Stream* stream = static_cast(userdata); + return stream->GetCursorPos() >= stream->GetSize(); + } + int Read(void* userdata, char* data, int size) { Stream* stream = static_cast(userdata); @@ -29,12 +35,6 @@ namespace Nz stream->SetCursorPos(static_cast(stream->GetCursorPos()) + static_cast(size)); } - int Eof(void* userdata) - { - Stream* stream = static_cast(userdata); - return stream->GetCursorPos() >= stream->GetSize(); - } - static stbi_io_callbacks callbacks = {Read, Skip, Eof}; bool IsSupported(const String& extension) From 0ffc3c6557d9d19ee4a265803843df56bd784f71 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:09:41 +0100 Subject: [PATCH 153/229] Core: Add ResourceSaver class Former-commit-id: 3c7fb9868058d897f1db831b207e9544688922fe --- include/Nazara/Core/ResourceSaver.hpp | 50 +++++++ include/Nazara/Core/ResourceSaver.inl | 190 ++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 include/Nazara/Core/ResourceSaver.hpp create mode 100644 include/Nazara/Core/ResourceSaver.inl diff --git a/include/Nazara/Core/ResourceSaver.hpp b/include/Nazara/Core/ResourceSaver.hpp new file mode 100644 index 000000000..c0e22566c --- /dev/null +++ b/include/Nazara/Core/ResourceSaver.hpp @@ -0,0 +1,50 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RESOURCESAVER_HPP +#define NAZARA_RESOURCESAVER_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class Stream; + + template + class ResourceSaver + { + friend Type; + + public: + using FormatQuerier = bool (*)(const String& format); + using FileSaver = bool (*)(const Type& resource, const String& filePath, const Parameters& parameters); + using StreamSaver = bool (*)(const Type& resource, const String& format, Stream& stream, const Parameters& parameters); + + ResourceSaver() = delete; + ~ResourceSaver() = delete; + + static bool IsFormatSupported(const String& extension); + + static bool SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters = Parameters()); + static bool SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters = Parameters()); + + static void RegisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver = nullptr); + static void UnregisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver = nullptr); + + private: + using Saver = std::tuple; + using SaverList = std::list; + }; +} + +#include + +#endif // NAZARA_RESOURCESAVER_HPP diff --git a/include/Nazara/Core/ResourceSaver.inl b/include/Nazara/Core/ResourceSaver.inl new file mode 100644 index 000000000..954b86a0e --- /dev/null +++ b/include/Nazara/Core/ResourceSaver.inl @@ -0,0 +1,190 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + /*! + * \ingroup core + * \class Nz::ResourceSaver + * \brief Core class that represents a list of saver functions for a specific resource type + */ + + /*! + * \brief Checks whether the extension of the file is supported + * \return true if supported + * + * \param extension Extension of the file + */ + template + bool ResourceSaver::IsFormatSupported(const String& extension) + { + for (Saver& saver : Type::s_savers) + { + ExtensionGetter isExtensionSupported = std::get<0>(loader); + + if (isExtensionSupported && isExtensionSupported(extension)) + return true; + } + + return false; + } + + /*! + * \brief Saves a resource to a file + * \return true if successfully saved + * + * \param resource Resource to save + * \param filePath Path to the file where the resource will be written + * \param parameters Parameters for the save + * + * \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 + * + * \seealso SaveToStream + */ + template + bool ResourceSaver::SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters) + { + NazaraAssert(parameters.IsValid(), "Invalid parameters"); + + String path = File::NormalizePath(filePath); + String ext = path.SubStringFrom('.', -1, true).ToLower(); + if (ext.IsEmpty()) + { + NazaraError("Failed to get file extension from \"" + filePath + '"'); + return false; + } + + File file(path); // Opened only is required + + bool found = false; + for (Saver& saver : Type::s_savers) + { + FormatQuerier formatQuerier = std::get<0>(saver); + if (!formatQuerier || !formatQuerier(ext)) + continue; + + found = true; + + StreamSaver streamSeaver = std::get<1>(saver); + FileSaver fileSaver = std::get<2>(saver); + + if (fileSaver) + { + if (fileSaver(resource, filePath, parameters)) + return true; + } + else + { + if (!file.Open(OpenMode_WriteOnly)) + { + NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode"); + return false; + } + + if (streamSeaver(resource, ext, file, parameters)) + return true; + } + + NazaraWarning("Saver failed"); + } + + if (found) + NazaraError("Failed to save resource: all savers failed"); + else + NazaraError("Failed to save resource: no saver found for extension \"" + ext + '"'); + + return false; + } + + /*! + * \brief Saves a resource to a stream + * \return true if successfully saved + * + * \param resource Resource to load + * \param stream Stream with write access where the resource data will be written + * \param format Data format to save the resource to + * \param parameters Parameters for the saving + * + * \seealso SaveToFile + */ + template + bool ResourceSaver::SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters) + { + NazaraAssert(stream.IsWritable(), "Stream is not writable"); + NazaraAssert(parameters.IsValid(), "Invalid parameters"); + + UInt64 streamPos = stream.GetCursorPos(); + bool found = false; + for (Saver& saver : Type::s_savers) + { + FormatQuerier formatQuerier = std::get<0>(saver); + if (!formatQuerier || !formatQuerier(format)) + continue; + + found = true; + + StreamSaver streamSeaver = std::get<1>(saver); + + // We move the stream to its old position + stream.SetCursorPos(streamPos); + + // Load of the resource + if (streamSeaver(resource, format, stream, parameters)) + return true; + + NazaraWarning("Saver failed"); + } + + if (found) + NazaraError("Failed to save resource: all savers failed"); + else + NazaraError("Failed to save resource: no saver found for format \"" + format + '"'); + + return false; + } + + /*! + * \brief Registers a saver + * + * \param formatQuerier A function to test whether the format (as a string) is supported by this saver + * \param streamSaver A function which saves the resource to a stream + * \param fileSaver Optional function which saves the resource directly to a file given a file path + * + * \remark The fileSaver argument is only present for compatibility with external savers which cannot be interfaced with streams + * \remark At least one saver is required + */ + template + void ResourceSaver::RegisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver) + { + NazaraAssert(formatQuerier, "A format querier is mandaroty"); + NazaraAssert(streamSaver || fileSaver, "A saver function is mandaroty"); + + Type::s_savers.push_front(std::make_tuple(formatQuerier, streamSaver, fileSaver)); + } + + /*! + * \brief Unregisters a saver + * + * \param formatQuerier A function to test whether the format (as a string) is supported by this saver + * \param streamSaver A function which saves the resource to a stream + * \param fileSaver A function function which saves the resource directly to a file given a file path + * + * \remark The saver will only be unregistered if the function pointers are exactly the same + */ + template + void ResourceSaver::UnregisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver) + { + Type::s_savers.remove(std::make_tuple(formatQuerier, streamSaver, fileSaver)); + } +} + +#include From 6f9d778749c13e87bf2a5233526ab3dd9fe3f689 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:10:06 +0100 Subject: [PATCH 154/229] Core/ResourceLoader: Replace checks by asserts Former-commit-id: 88be9b70d904856b888ee04829def85f1dee0bc6 --- include/Nazara/Core/ResourceLoader.inl | 79 ++++---------------------- 1 file changed, 12 insertions(+), 67 deletions(-) diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index f16ab6d6e..3661de08d 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -38,7 +38,7 @@ namespace Nz } /*! - * \brief Loads a resource from a filepath and parameters + * \brief Loads a resource from a file * \return true if successfully loaded * * \param resource Resource to load @@ -55,19 +55,8 @@ namespace Nz template bool ResourceLoader::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters) { - #if NAZARA_CORE_SAFE - if (!resource) - { - NazaraError("Pointer invalid"); - return false; - } - - if (!parameters.IsValid()) - { - NazaraError("Invalid parameters"); - return false; - } - #endif + NazaraAssert(resource, "Invalid resource"); + NazaraAssert(parameters.IsValid(), "Invalid parameters"); String path = File::NormalizePath(filePath); String ext = path.SubStringFrom('.', -1, true).ToLower(); @@ -173,25 +162,10 @@ namespace Nz template bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) { - #if NAZARA_CORE_SAFE - if (!resource) - { - NazaraError("Pointer invalid"); - return false; - } - - if (size == 0) - { - NazaraError("No data to load"); - return false; - } - - if (!parameters.IsValid()) - { - NazaraError("Invalid parameters"); - return false; - } - #endif + NazaraAssert(resource, "Invalid resource"); + NazaraAssert(data, "Invalid data pointer"); + NazaraAssert(size, "No data to load"); + NazaraAssert(parameters.IsValid(), "Invalid parameters"); MemoryView stream(data, size); @@ -269,25 +243,9 @@ namespace Nz template bool ResourceLoader::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters) { - #if NAZARA_CORE_SAFE - if (!resource) - { - NazaraError("Pointer invalid"); - return false; - } - - if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize()) - { - NazaraError("No data to load"); - return false; - } - - if (!parameters.IsValid()) - { - NazaraError("Invalid parameters"); - return false; - } - #endif + NazaraAssert(resource, "Invalid resource"); + NazaraAssert(stream.GetCursorPos() >= stream.GetSize(), "No data to load"); + NazaraAssert(parameters.IsValid(), "Invalid parameters"); UInt64 streamPos = stream.GetCursorPos(); bool found = false; @@ -336,21 +294,8 @@ namespace Nz template void ResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { - #if NAZARA_CORE_SAFE - if (streamLoader) - { - if (!checkFunc) - { - NazaraError("StreamLoader present without StreamChecker"); - return; - } - } - else if (!fileLoader && !memoryLoader) - { - NazaraError("Neither FileLoader nor MemoryLoader nor StreamLoader were present"); - return; - } - #endif + NazaraAssert(checkFunc || !streamLoader, "StreamLoader present without StreamChecker"); + NazaraAssert(fileLoader || memoryLoader || streamLoader, "A loader function is mandatory"); Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } From d6ff7d065e61897609c5b5131a4e18a2ca3c96fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:11:09 +0100 Subject: [PATCH 155/229] Utility/Image: Add saver (allowing to save images) Former-commit-id: df78d657256f8a6b7dad5ab11877aae7402608b3 --- include/Nazara/Renderer/Texture.hpp | 5 +- include/Nazara/Utility/Image.hpp | 15 ++ src/Nazara/Renderer/Texture.cpp | 24 +++ src/Nazara/Utility/Formats/STBLoader.cpp | 4 +- src/Nazara/Utility/Formats/STBLoader.hpp | 10 +- src/Nazara/Utility/Formats/STBSaver.cpp | 242 +++++++++++++++++++++++ src/Nazara/Utility/Formats/STBSaver.hpp | 21 ++ src/Nazara/Utility/Image.cpp | 95 +++++++++ src/Nazara/Utility/Utility.cpp | 7 +- 9 files changed, 413 insertions(+), 10 deletions(-) create mode 100644 src/Nazara/Utility/Formats/STBSaver.cpp create mode 100644 src/Nazara/Utility/Formats/STBSaver.hpp diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 15f3c11ec..73069aa37 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -22,7 +22,6 @@ namespace Nz { - class Texture; using TextureConstRef = ObjectRef; @@ -94,6 +93,10 @@ namespace Nz bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); bool LoadFaceFromStream(CubemapFace face, Stream& stream, const ImageParams& params = ImageParams()); + // Save + bool SaveToFile(const String& filePath, const ImageParams& params = ImageParams()); + bool SaveToStream(Stream& stream, const String& format, const ImageParams& params = ImageParams()); + bool SetMipmapRange(UInt8 minLevel, UInt8 maxLevel); bool Update(const Image& image, UInt8 level = 0); diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index ed9772a88..5ef32f2e7 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -43,12 +44,14 @@ namespace Nz using ImageLoader = ResourceLoader; using ImageManager = ResourceManager; using ImageRef = ObjectRef; + using ImageSaver = ResourceSaver; class NAZARA_UTILITY_API Image : public AbstractImage, public RefCounted, public Resource { friend ImageLibrary; friend ImageLoader; friend ImageManager; + friend ImageSaver; friend class Utility; public: @@ -107,6 +110,17 @@ namespace Nz bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + // LoadFace + bool LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params = ImageParams()); + bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); + bool LoadFaceFromStream(CubemapFace face, Stream& stream, const ImageParams& params = ImageParams()); + + // Save + bool SaveToFile(const String& filePath, const ImageParams& params = ImageParams()); + bool SaveToStream(Stream& stream, const String& format, const ImageParams& params = ImageParams()); + + //TODO: SaveArray, SaveCubemap, SaveFace + void SetLevelCount(UInt8 levelCount); bool SetPixelColor(const Color& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); @@ -165,6 +179,7 @@ namespace Nz static ImageLoader::LoaderList s_loaders; static ImageManager::ManagerMap s_managerMap; static ImageManager::ManagerParams s_managerParameters; + static ImageSaver::SaverList s_savers; }; } diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index fea1e2d6b..83b04ee33 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -825,6 +825,30 @@ namespace Nz return Update(image, Rectui(0, 0, faceSize, faceSize), face); } + bool Texture::SaveToFile(const String& filePath, const ImageParams& params) + { + Image image; + if (!Download(&image)) + { + NazaraError("Failed to download texture"); + return false; + } + + return image.SaveToFile(filePath, params); + } + + bool Texture::SaveToStream(Stream& stream, const String& format, const ImageParams& params) + { + Image image; + if (!Download(&image)) + { + NazaraError("Failed to download texture"); + return false; + } + + return image.SaveToStream(stream, format, params); + } + bool Texture::SetMipmapRange(UInt8 minLevel, UInt8 maxLevel) { #if NAZARA_RENDERER_SAFE diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index ef1a815b4..6954bd2b3 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -87,12 +87,12 @@ namespace Nz namespace Loaders { - void RegisterSTB() + void RegisterSTBLoader() { ImageLoader::RegisterLoader(IsSupported, Check, Load); } - void UnregisterSTB() + void UnregisterSTBLoader() { ImageLoader::UnregisterLoader(IsSupported, Check, Load); } diff --git a/src/Nazara/Utility/Formats/STBLoader.hpp b/src/Nazara/Utility/Formats/STBLoader.hpp index 4d8917ef5..03e08c72f 100644 --- a/src/Nazara/Utility/Formats/STBLoader.hpp +++ b/src/Nazara/Utility/Formats/STBLoader.hpp @@ -4,8 +4,8 @@ #pragma once -#ifndef NAZARA_LOADERS_STB_HPP -#define NAZARA_LOADERS_STB_HPP +#ifndef NAZARA_FORMATS_STBLOADER_HPP +#define NAZARA_FORMATS_STBLOADER_HPP #include @@ -13,9 +13,9 @@ namespace Nz { namespace Loaders { - void RegisterSTB(); - void UnregisterSTB(); + void RegisterSTBLoader(); + void UnregisterSTBLoader(); } } -#endif // NAZARA_LOADERS_STB_HPP +#endif // NAZARA_FORMATS_STBLOADER_HPP diff --git a/src/Nazara/Utility/Formats/STBSaver.cpp b/src/Nazara/Utility/Formats/STBSaver.cpp new file mode 100644 index 000000000..e68210d93 --- /dev/null +++ b/src/Nazara/Utility/Formats/STBSaver.cpp @@ -0,0 +1,242 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace + { + using FormatHandler = bool(*)(const Image& image, const ImageParams& parameters, Stream& stream); + + std::map s_formatHandlers; + + int ConvertToFloatFormat(Image& image) + { + switch (image.GetFormat()) + { + case PixelFormatType_R32F: + return 1; + + case PixelFormatType_RG32F: + return 2; + + case PixelFormatType_RGB32F: + return 3; + + case PixelFormatType_RGBA32F: + return 4; + + default: + { + if (PixelFormat::HasAlpha(image.GetFormat())) + { + if (!image.Convert(PixelFormatType_RGBA32F)) + break; + + return 4; + } + else + { + if (!image.Convert(PixelFormatType_RGB32F)) + break; + + return 3; + } + } + } + + return 0; + } + + int ConvertToIntegerFormat(Image& image) + { + switch (image.GetFormat()) + { + case PixelFormatType_L8: + case PixelFormatType_R8: + return 1; + + case PixelFormatType_LA8: + case PixelFormatType_RG8: + return 2; + + case PixelFormatType_RGB8: + return 3; + + case PixelFormatType_RGBA8: + return 4; + + default: + { + if (PixelFormat::HasAlpha(image.GetFormat())) + { + if (!image.Convert(PixelFormatType_RGBA8)) + break; + + return 4; + } + else + { + if (!image.Convert(PixelFormatType_RGB8)) + break; + + return 3; + } + } + } + + return 0; + } + + void WriteToStream(void* userdata, void* data, int size) + { + Stream* stream = static_cast(userdata); + if (stream->Write(data, size) != size) + throw std::runtime_error("Failed to write to stream"); + } + + bool FormatQuerier(const String& extension) + { + return s_formatHandlers.find(extension) != s_formatHandlers.end(); + } + + bool SaveToStream(const Image& image, const String& format, Stream& stream, const ImageParams& parameters) + { + NazaraUnused(parameters); + + if (!image.IsValid()) + { + NazaraError("Invalid image"); + return false; + } + + ImageType type = image.GetType(); + if (type != ImageType_1D && type != ImageType_2D) + { + NazaraError("Image type 0x" + String::Number(type, 16) + " is not "); + return false; + } + + auto it = s_formatHandlers.find(format); + NazaraAssert(it != s_formatHandlers.end(), "Invalid handler"); + + const FormatHandler& handler = it->second; + try + { + return handler(image, parameters, stream); + } + catch (const std::exception& e) + { + NazaraError(e.what()); + return false; + } + } + + bool SaveBMP(const Image& image, const ImageParams& parameters, Stream& stream) + { + Image tempImage(image); //< We're using COW here to prevent Image copy unless required + + int componentCount = ConvertToIntegerFormat(tempImage); + if (componentCount == 0) + { + NazaraError("Failed to convert image to suitable format"); + return false; + } + + if (!stbi_write_bmp_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels())) + { + NazaraError("Failed to write BMP to stream"); + return false; + } + + return true; + } + + bool SaveHDR(const Image& image, const ImageParams& parameters, Stream& stream) + { + Image tempImage(image); //< We're using COW here to prevent Image copy unless required + + int componentCount = ConvertToFloatFormat(tempImage); + if (componentCount == 0) + { + NazaraError("Failed to convert image to suitable format"); + return false; + } + + if (!stbi_write_hdr_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, reinterpret_cast(tempImage.GetConstPixels()))) + { + NazaraError("Failed to write BMP to stream"); + return false; + } + + return true; + } + + bool SavePNG(const Image& image, const ImageParams& parameters, Stream& stream) + { + Image tempImage(image); //< We're using COW here to prevent Image copy unless required + + int componentCount = ConvertToIntegerFormat(tempImage); + if (componentCount == 0) + { + NazaraError("Failed to convert image to suitable format"); + return false; + } + + if (!stbi_write_png_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels(), 0)) + { + NazaraError("Failed to write BMP to stream"); + return false; + } + + return true; + } + + bool SaveTGA(const Image& image, const ImageParams& parameters, Stream& stream) + { + Image tempImage(image); //< We're using COW here to prevent Image copy unless required + + int componentCount = ConvertToIntegerFormat(tempImage); + if (componentCount == 0) + { + NazaraError("Failed to convert image to suitable format"); + return false; + } + + if (!stbi_write_tga_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels())) + { + NazaraError("Failed to write BMP to stream"); + return false; + } + + return true; + } + } + + namespace Loaders + { + void RegisterSTBSaver() + { + s_formatHandlers["bmp"] = &SaveBMP; + s_formatHandlers["hdr"] = &SaveHDR; + s_formatHandlers["png"] = &SavePNG; + s_formatHandlers["tga"] = &SaveTGA; + + ImageSaver::RegisterSaver(FormatQuerier, SaveToStream); + } + + void UnregisterSTBSaver() + { + ImageSaver::UnregisterSaver(FormatQuerier, SaveToStream); + s_formatHandlers.clear(); + } + } +} diff --git a/src/Nazara/Utility/Formats/STBSaver.hpp b/src/Nazara/Utility/Formats/STBSaver.hpp new file mode 100644 index 000000000..9a511c07e --- /dev/null +++ b/src/Nazara/Utility/Formats/STBSaver.hpp @@ -0,0 +1,21 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_FORMATS_STBSAVER_HPP +#define NAZARA_FORMATS_STBSAVER_HPP + +#include + +namespace Nz +{ + namespace Loaders + { + void RegisterSTBSaver(); + void UnregisterSTBSaver(); + } +} + +#endif // NAZARA_FORMATS_STBSAVER_HPP diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index c8845f808..0965ed06e 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1066,6 +1066,100 @@ namespace Nz return LoadCubemapFromImage(image, cubemapParams); } + bool Image::LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params) + { + NazaraAssert(IsValid() && IsCubemap(), "Texture must be a valid cubemap"); + + Image image; + if (!image.LoadFromFile(filePath, params)) + { + NazaraError("Failed to load image"); + return false; + } + + if (!image.Convert(GetFormat())) + { + NazaraError("Failed to convert image to texture format"); + return false; + } + + unsigned int faceSize = GetWidth(); + if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + { + NazaraError("Image size must match texture face size"); + return false; + } + + Copy(image, Rectui(0, 0, faceSize, faceSize), Vector3ui(0, 0, face)); + return true; + } + + bool Image::LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params) + { + NazaraAssert(IsValid() && IsCubemap(), "Texture must be a valid cubemap"); + + Image image; + if (!image.LoadFromMemory(data, size, params)) + { + NazaraError("Failed to load image"); + return false; + } + + if (!image.Convert(GetFormat())) + { + NazaraError("Failed to convert image to texture format"); + return false; + } + + unsigned int faceSize = GetWidth(); + if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + { + NazaraError("Image size must match texture face size"); + return false; + } + + Copy(image, Rectui(0, 0, faceSize, faceSize), Vector3ui(0, 0, face)); + return true; + } + + bool Image::LoadFaceFromStream(CubemapFace face, Stream& stream, const ImageParams& params) + { + NazaraAssert(IsValid() && IsCubemap(), "Texture must be a valid cubemap"); + + Image image; + if (!image.LoadFromStream(stream, params)) + { + NazaraError("Failed to load image"); + return false; + } + + if (!image.Convert(GetFormat())) + { + NazaraError("Failed to convert image to texture format"); + return false; + } + + unsigned int faceSize = GetWidth(); + if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + { + NazaraError("Image size must match texture face size"); + return false; + } + + Copy(image, Rectui(0, 0, faceSize, faceSize), Vector3ui(0, 0, face)); + return true; + } + + bool Image::SaveToFile(const String& filePath, const ImageParams& params) + { + return ImageSaver::SaveToFile(*this, filePath, params); + } + + bool Image::SaveToStream(Stream& stream, const String& format, const ImageParams& params) + { + return ImageSaver::SaveToStream(*this, stream, format, params); + } + void Image::SetLevelCount(UInt8 levelCount) { #if NAZARA_UTILITY_SAFE @@ -1377,4 +1471,5 @@ namespace Nz ImageLoader::LoaderList Image::s_loaders; ImageManager::ManagerMap Image::s_managerMap; ImageManager::ManagerParams Image::s_managerParameters; + ImageSaver::SaverList Image::s_savers; } diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index cc4687197..17a1bd049 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace Nz @@ -112,7 +113,8 @@ namespace Nz Loaders::RegisterFreeType(); // Image - Loaders::RegisterSTB(); // Loader générique (STB) + Loaders::RegisterSTBLoader(); // Generic loader (STB) + Loaders::RegisterSTBSaver(); // Generic saver (STB) /// Loaders spécialisés // Animation @@ -155,7 +157,8 @@ namespace Nz Loaders::UnregisterMD5Anim(); Loaders::UnregisterMD5Mesh(); Loaders::UnregisterPCX(); - Loaders::UnregisterSTB(); + Loaders::UnregisterSTBLoader(); + Loaders::UnregisterSTBSaver(); Window::Uninitialize(); VertexDeclaration::Uninitialize(); From b524d9395afa43d120b082cd99797dba6710c583 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:12:02 +0100 Subject: [PATCH 156/229] Core/String: Fix documentation comments Former-commit-id: 02fd62caaafce0376b387d9c8365b3ca89e32a78 --- src/Nazara/Core/String.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 8abeb2d02..acbafbd5c 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -5855,13 +5855,12 @@ namespace Nz } /*! - * \brief Serializes the string + * \brief Serializes a string * \return true if successful * * \param context Context of serialization * \param string String to serialize */ - bool Serialize(SerializationContext& context, const String& string) { if (!Serialize(context, string.GetSize())) @@ -5871,13 +5870,12 @@ namespace Nz } /*! - * \brief Unserializes the string + * \brief Unserializes a string * \return true if successful * * \param context Context of unserialization * \param string String to unserialize */ - bool Unserialize(SerializationContext& context, String* string) { UInt32 size; From dce587bd63c3fc9f7428ad06f3b1c9b8c7c4ad51 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:37:17 +0100 Subject: [PATCH 157/229] Add support for custom resource parameters And allow users to skip a precise loader using them Former-commit-id: 297af2e4a24ad67c343aae5d89352abf4ea05f63 --- include/Nazara/Audio/Music.hpp | 3 ++- include/Nazara/Audio/SoundBuffer.hpp | 3 ++- include/Nazara/Core/ResourceLoader.hpp | 2 ++ include/Nazara/Core/ResourceParameters.hpp | 20 +++++++++++++++++++ include/Nazara/Core/ResourceSaver.hpp | 2 ++ include/Nazara/Graphics/Material.hpp | 3 ++- include/Nazara/Graphics/Model.hpp | 3 ++- include/Nazara/Graphics/SkeletalModel.hpp | 2 +- include/Nazara/Utility/Animation.hpp | 3 ++- include/Nazara/Utility/Font.hpp | 3 ++- include/Nazara/Utility/Image.hpp | 3 ++- include/Nazara/Utility/Mesh.hpp | 3 ++- src/Nazara/Graphics/Formats/MeshLoader.cpp | 10 ++++++++-- src/Nazara/Graphics/Formats/OBJLoader.cpp | 5 ++++- src/Nazara/Graphics/Formats/TextureLoader.cpp | 5 ++++- src/Nazara/Utility/Formats/DDSLoader.cpp | 4 +++- src/Nazara/Utility/Formats/FreeTypeLoader.cpp | 4 +++- src/Nazara/Utility/Formats/MD2Loader.cpp | 4 +++- src/Nazara/Utility/Formats/MD5AnimLoader.cpp | 4 +++- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 4 +++- src/Nazara/Utility/Formats/PCXLoader.cpp | 4 +++- src/Nazara/Utility/Formats/STBLoader.cpp | 4 +++- 22 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 include/Nazara/Core/ResourceParameters.hpp diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 50935ac79..d08732fa7 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -12,10 +12,11 @@ #include #include #include +#include namespace Nz { - struct MusicParams + struct MusicParams : ResourceParameters { bool forceMono = false; diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index b144e71ad..2b02847b4 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -16,12 +16,13 @@ #include #include #include +#include #include #include namespace Nz { - struct SoundBufferParams + struct SoundBufferParams : ResourceParameters { bool forceMono = false; diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index 73b2dfa52..4bc58b265 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -21,6 +21,8 @@ namespace Nz template class ResourceLoader { + static_assert(std::is_base_of::value, "ResourceParameters must be a base of Parameters"); + friend Type; public: diff --git a/include/Nazara/Core/ResourceParameters.hpp b/include/Nazara/Core/ResourceParameters.hpp new file mode 100644 index 000000000..e4f32e06a --- /dev/null +++ b/include/Nazara/Core/ResourceParameters.hpp @@ -0,0 +1,20 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RESOURCEPARAMETERS_HPP +#define NAZARA_RESOURCEPARAMETERS_HPP + +#include + +namespace Nz +{ + struct ResourceParameters + { + ParameterList custom; + }; +} + +#endif // NAZARA_RESOURCEPARAMETERS_HPP diff --git a/include/Nazara/Core/ResourceSaver.hpp b/include/Nazara/Core/ResourceSaver.hpp index c0e22566c..470166014 100644 --- a/include/Nazara/Core/ResourceSaver.hpp +++ b/include/Nazara/Core/ResourceSaver.hpp @@ -21,6 +21,8 @@ namespace Nz template class ResourceSaver { + static_assert(std::is_base_of::value, "ResourceParameters must be a base of Parameters"); + friend Type; public: diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 8f6cdb920..a2d30b643 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ namespace Nz { - struct NAZARA_GRAPHICS_API MaterialParams + struct NAZARA_GRAPHICS_API MaterialParams : ResourceParameters { bool loadAlphaMap = true; bool loadDiffuseMap = true; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 9f7506c12..b4564d1b8 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -10,13 +10,14 @@ #include #include #include +#include #include #include #include namespace Nz { - struct NAZARA_GRAPHICS_API ModelParameters + struct NAZARA_GRAPHICS_API ModelParameters : ResourceParameters { ModelParameters(); diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 6ae25923e..99791168a 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -18,7 +18,7 @@ namespace Nz { - struct NAZARA_GRAPHICS_API SkeletalModelParameters : public ModelParameters + struct NAZARA_GRAPHICS_API SkeletalModelParameters : ModelParameters { bool loadAnimation = true; AnimationParams animation; diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 162d86e35..e196a0f77 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,7 @@ namespace Nz { - struct NAZARA_UTILITY_API AnimationParams + struct NAZARA_UTILITY_API AnimationParams : ResourceParameters { // La frame de fin à charger unsigned int endFrame = std::numeric_limits::max(); diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index ef801d5a2..58ff341b5 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -14,13 +14,14 @@ #include #include #include +#include #include #include #include namespace Nz { - struct NAZARA_UTILITY_API FontParams + struct NAZARA_UTILITY_API FontParams : ResourceParameters { bool IsValid() const; }; diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 5ef32f2e7..cefc606af 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ namespace Nz { - struct NAZARA_UTILITY_API ImageParams + struct NAZARA_UTILITY_API ImageParams : ResourceParameters { // Le format dans lequel l'image doit être chargée (Undefined pour le format le plus proche de l'original) PixelFormatType loadFormat = PixelFormatType_Undefined; diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 17857704a..433f50ab5 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ namespace Nz { - struct NAZARA_UTILITY_API MeshParams + struct NAZARA_UTILITY_API MeshParams : ResourceParameters { MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index bce371e51..af6280ef6 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -17,7 +17,10 @@ namespace Nz Ternary CheckStatic(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); - NazaraUnused(parameters); + + bool skip; + if (parameters.custom.GetBooleanParameter("NativeStaticMeshLoader_Skip", &skip) && skip) + return Ternary_False; return Ternary_Unknown; } @@ -66,7 +69,10 @@ namespace Nz Ternary CheckAnimated(Stream& stream, const SkeletalModelParameters& parameters) { NazaraUnused(stream); - NazaraUnused(parameters); + + bool skip; + if (parameters.custom.GetBooleanParameter("NativeAnimatedMeshLoader_Skip", &skip) && skip) + return Ternary_False; return Ternary_Unknown; } diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Graphics/Formats/OBJLoader.cpp index a81acae1b..af4378f15 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.cpp @@ -33,7 +33,10 @@ namespace Nz Ternary Check(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); - NazaraUnused(parameters); + + bool skip; + if (parameters.custom.GetBooleanParameter("NativeOBJLoader_Skip", &skip) && skip) + return Ternary_False; return Ternary_Unknown; } diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index 2f8dc2910..9c1de9182 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -15,7 +15,10 @@ namespace Nz Ternary Check(Stream& stream, const MaterialParams& parameters) { NazaraUnused(stream); - NazaraUnused(parameters); + + bool skip; + if (parameters.custom.GetBooleanParameter("NativeTextureLoader_Skip", &skip) && skip) + return Ternary_False; return Ternary_Unknown; } diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index b38ed4470..f60e13cb9 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -22,7 +22,9 @@ namespace Nz Ternary Check(Stream& stream, const ImageParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativeDDSLoader_Skip", &skip) && skip) + return Ternary_False; UInt32 magic; if (stream.Read(&magic, sizeof(UInt32)) == sizeof(UInt32)) diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index 2f5c2ef8f..4fcc66c9c 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -348,7 +348,9 @@ namespace Nz Ternary Check(Stream& stream, const FontParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativeFreeTypeLoader_Skip", &skip) && skip) + return Ternary_False; FreeTypeStream face; face.SetStream(stream); diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index ea685cc6f..ee37e51c8 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -28,7 +28,9 @@ namespace Nz Ternary Check(Stream& stream, const MeshParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativeMD2Loader_Skip", &skip) && skip) + return Ternary_False; UInt32 magic[2]; if (stream.Read(&magic[0], 2*sizeof(UInt32)) == 2*sizeof(UInt32)) diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index 1950037c1..3a03a5be5 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -17,7 +17,9 @@ namespace Nz Ternary Check(Stream& stream, const AnimationParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativeMD5AnimLoader_Skip", &skip) && skip) + return Ternary_False; MD5AnimParser parser(stream); return parser.Check(); diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 9bf16f055..c17cd9176 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -22,7 +22,9 @@ namespace Nz Ternary Check(Stream& stream, const MeshParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativeMD5MeshLoader_Skip", &skip) && skip) + return Ternary_False; MD5MeshParser parser(stream); return parser.Check(); diff --git a/src/Nazara/Utility/Formats/PCXLoader.cpp b/src/Nazara/Utility/Formats/PCXLoader.cpp index c337409bf..cfc487e49 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.cpp +++ b/src/Nazara/Utility/Formats/PCXLoader.cpp @@ -47,7 +47,9 @@ namespace Nz Ternary Check(Stream& stream, const ImageParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativePCXLoader_Skip", &skip) && skip) + return Ternary_False; UInt8 manufacturer; if (stream.Read(&manufacturer, 1) == 1) diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 6954bd2b3..183416045 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -45,7 +45,9 @@ namespace Nz Ternary Check(Stream& stream, const ImageParams& parameters) { - NazaraUnused(parameters); + bool skip; + if (parameters.custom.GetBooleanParameter("NativeSTBLoader_Skip", &skip) && skip) + return Ternary_False; int width, height, bpp; if (stbi_info_from_callbacks(&callbacks, &stream, &width, &height, &bpp)) From c935c1a293573d222ccd4cff26105e7e8a512bea Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:39:08 +0100 Subject: [PATCH 158/229] Graphics/OBJLoader: Allow users to specifiy a vertex count cache when loading Former-commit-id: 87ebc2aefe2c2091fd483793f880724e1ed6ac3d --- include/Nazara/Utility/Formats/OBJParser.hpp | 2 +- src/Nazara/Graphics/Formats/OBJLoader.cpp | 6 +++++- src/Nazara/Utility/Formats/OBJParser.cpp | 10 +++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 3decd248f..90e653f93 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -54,7 +54,7 @@ namespace Nz const Vector3f* GetTexCoords() const; unsigned int GetTexCoordCount() const; - bool Parse(); + bool Parse(std::size_t reservedVertexCount = 100); private: bool Advance(bool required = true); diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Graphics/Formats/OBJLoader.cpp index af4378f15..a85a734d0 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.cpp @@ -133,8 +133,12 @@ namespace Nz bool Load(Model* model, Stream& stream, const ModelParameters& parameters) { + int reservedVertexCount; + if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount)) + reservedVertexCount = 100; + OBJParser parser(stream); - if (!parser.Parse()) + if (!parser.Parse(reservedVertexCount)) { NazaraError("OBJ parser failed"); return false; diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index 64132f586..c0daf1f84 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -82,7 +82,7 @@ namespace Nz return m_texCoords.size(); } - bool OBJParser::Parse() + bool OBJParser::Parse(std::size_t reservedVertexCount) { String matName, meshName; matName = meshName = "default"; @@ -95,10 +95,10 @@ namespace Nz m_positions.clear(); m_texCoords.clear(); - // Beaucoup de meshs font plus de 100 sommets, préparons le terrain - m_normals.reserve(100); - m_positions.reserve(100); - m_texCoords.reserve(100); + // Reserve some space for incoming vertices + m_normals.reserve(reservedVertexCount); + m_positions.reserve(reservedVertexCount); + m_texCoords.reserve(reservedVertexCount); // On va regrouper les meshs par nom et par matériau using FaceVec = std::vector; From d349b9583e36f9694ce773f2dae19b6673b80edf Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:43:11 +0100 Subject: [PATCH 159/229] Core: Fix missing include Former-commit-id: 76e4ff0d2bd3e3b6865e84f6ef0142a195a5755a --- include/Nazara/Core/ResourceLoader.hpp | 1 + include/Nazara/Core/ResourceManager.hpp | 1 + include/Nazara/Core/ResourceSaver.hpp | 1 + 3 files changed, 3 insertions(+) diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index 4bc58b265..b0640dcbc 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/include/Nazara/Core/ResourceManager.hpp b/include/Nazara/Core/ResourceManager.hpp index fa3dd63ec..ca5735811 100644 --- a/include/Nazara/Core/ResourceManager.hpp +++ b/include/Nazara/Core/ResourceManager.hpp @@ -8,6 +8,7 @@ #define NAZARA_RESOURCEMANAGER_HPP #include +#include #include #include diff --git a/include/Nazara/Core/ResourceSaver.hpp b/include/Nazara/Core/ResourceSaver.hpp index 470166014..be2880cd0 100644 --- a/include/Nazara/Core/ResourceSaver.hpp +++ b/include/Nazara/Core/ResourceSaver.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include From 1a95c314ff09d794da3909c2dd59f7f07a37da6f Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 8 Mar 2016 13:58:09 +0100 Subject: [PATCH 160/229] Core/ParameterList: Make errors silent by default Former-commit-id: 38d1613681a65194cb7392903c9bc20f912561a3 --- include/Nazara/Core/ParameterList.hpp | 4 +- src/Nazara/Core/ParameterList.cpp | 135 ++++++++++++-------------- 2 files changed, 64 insertions(+), 75 deletions(-) diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index bd4b01b58..2475185d7 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -86,10 +86,10 @@ namespace Nz Value value; }; - using ParameterMap = std::unordered_map; - + Parameter& CreateValue(const String& name); void DestroyValue(Parameter& parameter); + using ParameterMap = std::unordered_map; ParameterMap m_parameters; }; } diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 405ebd1cd..5edd8f976 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -49,21 +50,23 @@ namespace Nz } /*! - * \brief Gets the boolean parameter by name + * \brief Gets a boolean parameter by name * \return true if success * * \param name Name of the variable * \param value Value to set * * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a silent NazaraError if name is not a variable + * \remark Produces a silent NazaraError if value could not be convertible */ bool ParameterList::GetBooleanParameter(const String& name, bool* value) const { NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -105,21 +108,23 @@ namespace Nz } /*! - * \brief Gets the float parameter by name + * \brief Gets a float parameter by name * \return true if success * * \param name Name of the variable * \param value Value to set * * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a silent NazaraError if name is not a variable + * \remark Produces a silent NazaraError if value could not be convertible */ bool ParameterList::GetFloatParameter(const String& name, float* value) const { NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -161,21 +166,23 @@ namespace Nz } /*! - * \brief Gets the integer parameter by name + * \brief Gets a integer parameter by name * \return true if success * * \param name Name of the variable * \param value Value to set * * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a silent NazaraError if name is not a variable + * \remark Produces a silent NazaraError if value could not be convertible */ bool ParameterList::GetIntegerParameter(const String& name, int* value) const { NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -222,15 +229,13 @@ namespace Nz } /*! - * \brief Gets the parameter by name - * \return true if success + * \brief Gets a parameter type by name + * \return true if the parameter is present * * \param name Name of the variable - * \param type Type to set + * \param type Pointer to a variable to hold result * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a NazaraAssert if type is invalid */ bool ParameterList::GetParameterType(const String& name, ParameterType* type) const @@ -247,21 +252,23 @@ namespace Nz } /*! - * \brief Gets the pointer parameter by name + * \brief Gets a pointer parameter by name * \return true if success * * \param name Name of the variable * \param value Value to set * * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a silent NazaraError if name is not a variable + * \remark Produces a silent NazaraError if value could not be convertible */ bool ParameterList::GetPointerParameter(const String& name, void** value) const { NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -292,21 +299,23 @@ namespace Nz } /*! - * \brief Gets the string parameter by name + * \brief Gets a string parameter by name * \return true if success * * \param name Name of the variable * \param value Value to set * * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a silent NazaraError if name is not a variable + * \remark Produces a silent NazaraError if value could not be convertible */ bool ParameterList::GetStringParameter(const String& name, String* value) const { NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -350,21 +359,23 @@ namespace Nz } /*! - * \brief Gets the user parameter by name + * \brief Gets a user parameter by name * \return true if success * * \param name Name of the variable * \param value Value to set * * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a NazaraError if name is not a variable - * \remark Produces a NazaraError if value could not be convertible + * \remark Produces a silent NazaraError if name is not a variable + * \remark Produces a silent NazaraError if value could not be convertible */ bool ParameterList::GetUserdataParameter(const String& name, void** value) const { NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + auto it = m_parameters.find(name); if (it == m_parameters.end()) { @@ -422,12 +433,7 @@ namespace Nz void ParameterList::SetParameter(const String& name) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_None; } @@ -440,12 +446,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, const String& value) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_String; PlacementNew(¶meter.value.stringVal, value); @@ -460,12 +461,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, const char* value) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_String; PlacementNew(¶meter.value.stringVal, value); @@ -480,12 +476,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, void* value) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Pointer; parameter.value.ptrVal = value; } @@ -500,12 +491,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Userdata; parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); } @@ -519,12 +505,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, bool value) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Boolean; parameter.value.boolVal = value; } @@ -538,12 +519,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, float value) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Float; parameter.value.floatVal = value; } @@ -557,12 +533,7 @@ namespace Nz void ParameterList::SetParameter(const String& name, int value) { - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - + Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Integer; parameter.value.intVal = value; } @@ -612,12 +583,30 @@ namespace Nz return *this; } + /*! + * \brief Create an uninitialized value of a set name + * + * \param name Name of the parameter + * \param value Value of the parameter + * + * \remark The previous value if any gets destroyed + */ + ParameterList::Parameter& ParameterList::CreateValue(const String& name) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + return parameter; + } + /*! * \brief Destroys the value for the parameter * * \param parameter Parameter to destroy */ - void ParameterList::DestroyValue(Parameter& parameter) { switch (parameter.type) From b4e98dc7fc59d24877efcaefb7f1d8b7d4ffa412 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Mar 2016 12:41:39 +0100 Subject: [PATCH 161/229] Formats: Change skip string format Former-commit-id: 75952d298efb69bd9b77df31ee8dc1548442d071 --- src/Nazara/Graphics/Formats/MeshLoader.cpp | 4 ++-- src/Nazara/Graphics/Formats/OBJLoader.cpp | 2 +- src/Nazara/Graphics/Formats/TextureLoader.cpp | 2 +- src/Nazara/Utility/Formats/DDSLoader.cpp | 2 +- src/Nazara/Utility/Formats/FreeTypeLoader.cpp | 2 +- src/Nazara/Utility/Formats/MD2Loader.cpp | 2 +- src/Nazara/Utility/Formats/MD5AnimLoader.cpp | 2 +- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 2 +- src/Nazara/Utility/Formats/PCXLoader.cpp | 2 +- src/Nazara/Utility/Formats/STBLoader.cpp | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index af6280ef6..b915c6f2e 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -19,7 +19,7 @@ namespace Nz NazaraUnused(stream); bool skip; - if (parameters.custom.GetBooleanParameter("NativeStaticMeshLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeMeshLoader", &skip) && skip) return Ternary_False; return Ternary_Unknown; @@ -71,7 +71,7 @@ namespace Nz NazaraUnused(stream); bool skip; - if (parameters.custom.GetBooleanParameter("NativeAnimatedMeshLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeAnimatedMeshLoader", &skip) && skip) return Ternary_False; return Ternary_Unknown; diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Graphics/Formats/OBJLoader.cpp index a85a734d0..09ad743d7 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.cpp @@ -35,7 +35,7 @@ namespace Nz NazaraUnused(stream); bool skip; - if (parameters.custom.GetBooleanParameter("NativeOBJLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeOBJLoader", &skip) && skip) return Ternary_False; return Ternary_Unknown; diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index 9c1de9182..7530726fb 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -17,7 +17,7 @@ namespace Nz NazaraUnused(stream); bool skip; - if (parameters.custom.GetBooleanParameter("NativeTextureLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeTextureLoader", &skip) && skip) return Ternary_False; return Ternary_Unknown; diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index f60e13cb9..8f08abcf2 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -23,7 +23,7 @@ namespace Nz Ternary Check(Stream& stream, const ImageParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativeDDSLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeDDSLoader", &skip) && skip) return Ternary_False; UInt32 magic; diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index 4fcc66c9c..aed76d608 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -349,7 +349,7 @@ namespace Nz Ternary Check(Stream& stream, const FontParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativeFreeTypeLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeFreeTypeLoader", &skip) && skip) return Ternary_False; FreeTypeStream face; diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index ee37e51c8..856a73823 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -29,7 +29,7 @@ namespace Nz Ternary Check(Stream& stream, const MeshParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativeMD2Loader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeMD2Loader", &skip) && skip) return Ternary_False; UInt32 magic[2]; diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index 3a03a5be5..d079dc426 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -18,7 +18,7 @@ namespace Nz Ternary Check(Stream& stream, const AnimationParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativeMD5AnimLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeMD5AnimLoader", &skip) && skip) return Ternary_False; MD5AnimParser parser(stream); diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index c17cd9176..4c4b61bae 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -23,7 +23,7 @@ namespace Nz Ternary Check(Stream& stream, const MeshParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativeMD5MeshLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeMD5MeshLoader", &skip) && skip) return Ternary_False; MD5MeshParser parser(stream); diff --git a/src/Nazara/Utility/Formats/PCXLoader.cpp b/src/Nazara/Utility/Formats/PCXLoader.cpp index cfc487e49..1dc7622bd 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.cpp +++ b/src/Nazara/Utility/Formats/PCXLoader.cpp @@ -48,7 +48,7 @@ namespace Nz Ternary Check(Stream& stream, const ImageParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativePCXLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativePCXLoader", &skip) && skip) return Ternary_False; UInt8 manufacturer; diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 183416045..3ca5b3708 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -46,7 +46,7 @@ namespace Nz Ternary Check(Stream& stream, const ImageParams& parameters) { bool skip; - if (parameters.custom.GetBooleanParameter("NativeSTBLoader_Skip", &skip) && skip) + if (parameters.custom.GetBooleanParameter("SkipNativeSTBLoader", &skip) && skip) return Ternary_False; int width, height, bpp; From 8e3c542049d347e676f054de28078b3da2913073 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Mar 2016 13:52:39 +0100 Subject: [PATCH 162/229] Core/ByteStream: Remove assertion on ByteStream pointer Former-commit-id: 438b669e039cfdece251f4918926df9268bb01c1 --- include/Nazara/Core/ByteStream.inl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl index 83062d3ba..dadc056ca 100644 --- a/include/Nazara/Core/ByteStream.inl +++ b/include/Nazara/Core/ByteStream.inl @@ -9,14 +9,10 @@ namespace Nz { /*! * \brief Constructs a ByteStream object with a stream - * - * \remark Produces a NazaraAssert if stream is invalid */ inline ByteStream::ByteStream(Stream* stream) { - NazaraAssert(stream, "Invalid stream"); - m_context.stream = stream; } From 3f9a4170f165ed3c57d088a51b1281ece33f030b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Mar 2016 13:54:04 +0100 Subject: [PATCH 163/229] Network: Add RUdpConnection class (experimental) Currently missing an external RUdpClient class, ping handling, some messages but should basically works Former-commit-id: 6ebd181a4804094c62aedb8e3ba7876a7b06acdc --- include/Nazara/Network/Enums.hpp | 27 ++ include/Nazara/Network/RUdpConnection.hpp | 158 +++++++ include/Nazara/Network/RUdpConnection.inl | 126 ++++++ include/Nazara/Network/RUdpMessage.hpp | 23 ++ src/Nazara/Network/Network.cpp | 8 + src/Nazara/Network/RUdpConnection.cpp | 482 ++++++++++++++++++++++ 6 files changed, 824 insertions(+) create mode 100644 include/Nazara/Network/RUdpConnection.hpp create mode 100644 include/Nazara/Network/RUdpConnection.inl create mode 100644 include/Nazara/Network/RUdpMessage.hpp create mode 100644 src/Nazara/Network/RUdpConnection.cpp diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 3d077519a..81c5f7c3d 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -11,6 +11,12 @@ namespace Nz { enum NetCode : UInt16 { + NetCode_Acknowledge = 0x9A4E, + NetCode_AcknowledgeConnection = 0xC108, + NetCode_Ping = 0x96AC, + NetCode_Pong = 0x974C, + NetCode_RequestConnection = 0xF27D, + NetCode_Invalid = 0x0000 }; @@ -24,6 +30,27 @@ namespace Nz NetProtocol_Max = NetProtocol_Unknown }; + enum PacketPriority + { + PacketPriority_High = 1, //< High-priority packet, will be sent quickly + PacketPriority_Immediate = 0, //< Immediate priority, will be sent immediately + PacketPriority_Medium = 2, //< Medium-priority packet, will be sent as regular + PacketPriority_Low = 3, //< Low-priority packet, may take some time to be sent + + PacketPriority_Lowest = PacketPriority_Low, + PacketPriority_Highest = PacketPriority_Immediate, + PacketPriority_Max = PacketPriority_Low + }; + + enum PacketReliability + { + PacketReliability_Reliable, //< Packet will be resent if lost + PacketReliability_ReliableOrdered, //< Packet will be resent if lost and will only arrive in order + PacketReliability_Unreliable, //< Packet won't be resent if lost + + PacketReliability_Max = PacketReliability_Unreliable + }; + enum ResolveError { ResolveError_NoError, diff --git a/include/Nazara/Network/RUdpConnection.hpp b/include/Nazara/Network/RUdpConnection.hpp new file mode 100644 index 000000000..20285b6fc --- /dev/null +++ b/include/Nazara/Network/RUdpConnection.hpp @@ -0,0 +1,158 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RUDPSERVER_HPP +#define NAZARA_RUDPSERVER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class RUdpClient; + + class NAZARA_NETWORK_API RUdpConnection + { + friend class Network; + + public: + using SequenceIndex = UInt16; + + RUdpConnection(); + RUdpConnection(const RUdpConnection&) = delete; + RUdpConnection(RUdpConnection&&) = default; + ~RUdpConnection() = default; + + inline void Close(); + + bool Connect(const IpAddress& remoteAddress); + bool Connect(const String& hostName, NetProtocol protocol = NetProtocol_Any, const String& service = "http", ResolveError* error = nullptr); + inline void Disconnect(); + + inline IpAddress GetBoundAddress() const; + inline UInt16 GetBoundPort() const; + inline SocketError GetLastError() const; + + inline bool Listen(NetProtocol protocol, UInt16 port = 64266, unsigned int queueSize = 10); + bool Listen(const IpAddress& address, unsigned int queueSize = 10); + + bool PollMessage(RUdpMessage* message); + + bool Send(const IpAddress& clientIp, PacketPriority priority, PacketReliability reliability, const NetPacket& packet); + + inline void SetProtocolId(UInt32 protocolId); + inline void SetTimeBeforeAck(UInt32 ms); + + void Update(); + + RUdpConnection& operator=(const RUdpConnection&) = delete; + RUdpConnection& operator=(RUdpConnection&&) = default; + + static constexpr std::size_t MessageHeader = sizeof(UInt16) + 2 * sizeof(SequenceIndex) + sizeof(UInt32); //< Protocol ID (begin) + Sequence ID + Remote Sequence ID + Ack bitfield + static constexpr std::size_t MessageFooter = sizeof(UInt16); //< Protocol ID (end) + + // Signals: + NazaraSignal(OnConnectedToPeer, RUdpConnection* /*connection*/); + NazaraSignal(OnPeerAcknowledged, RUdpConnection* /*connection*/, const IpAddress& /*adress*/); + NazaraSignal(OnPeerConnection, RUdpConnection* /*connection*/, const IpAddress& /*adress*/); + NazaraSignal(OnPeerDisconnected, RUdpConnection* /*connection*/, const IpAddress& /*adress*/); + + private: + struct PeerData; + struct PendingAckPacket; + struct PendingPacket; + + enum PeerState + { + PeerState_Aknowledged, //< A connection request from this peer has been received, we're waiting for another packet to validate + PeerState_Connected, //< Connection is working in both-ways + PeerState_Connecting, //< A connection request has been made + PeerState_WillAck //< Connected, received one or more packets and has no packets to send, waiting before sending an empty ack packet + }; + + void DisconnectPeer(std::size_t peerIndex); + void EnqueuePacket(PeerData& peer, PacketPriority priority, PacketReliability reliability, const NetPacket& packet); + void EnqueuePacketInternal(PeerData& peer, PacketPriority priority, PacketReliability reliability, NetPacket&& data); + bool InitSocket(NetProtocol protocol); + void ProcessAcks(PeerData& peer, SequenceIndex lastAck, UInt32 ackBits); + PeerData& RegisterPeer(const IpAddress& address, PeerState state); + void OnClientRequestingConnection(const IpAddress& address, SequenceIndex sequenceId, UInt64 token); + void OnPacketLost(PeerData& peer, PendingAckPacket&& packet); + void OnPacketReceived(const IpAddress& peerIp, NetPacket&& packet); + void SendPacket(PeerData& peer, PendingPacket&& packet); + + static inline unsigned int ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2); + static inline bool HasPendingPackets(PeerData& peer); + static bool Initialize(); + static inline bool IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2); + static inline bool IsReliable(PacketReliability reliability); + static void Uninitialize(); + + struct PendingPacket + { + PacketPriority priority; + PacketReliability reliability; + NetPacket data; + }; + + struct PendingAckPacket + { + PacketPriority priority; + PacketReliability reliability; + NetPacket data; + SequenceIndex sequenceId; + UInt64 timeSent; + }; + + struct PeerData //TODO: Move this to RUdpClient + { + std::array, PacketPriority_Max + 1> pendingPackets; + std::deque pendingAckQueue; + std::set receivedQueue; + std::size_t index; + PeerState state; + IpAddress address; + SequenceIndex localSequence; + SequenceIndex remoteSequence; + UInt32 roundTripTime; + UInt64 lastPacketTime; + UInt64 lastPingTime; + UInt64 stateData1; + }; + + std::unordered_map m_peerByIP; + std::queue m_receivedMessages; + std::size_t m_peerIterator; + std::vector m_peers; + Bitset m_activeClients; + Clock m_clock; + SocketError m_lastError; + UdpSocket m_socket; + UInt32 m_forceAckSendTime; + UInt32 m_pingInterval; + UInt32 m_protocol; + UInt32 m_timeBeforePing; + UInt32 m_timeBeforeTimeOut; + UInt64 m_currentTime; + bool m_shouldAcceptConnections; + + static std::mt19937_64 s_randomGenerator; + }; +} + +#include + +#endif // NAZARA_RUDPSERVER_HPP \ No newline at end of file diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl new file mode 100644 index 000000000..cfb598bb9 --- /dev/null +++ b/include/Nazara/Network/RUdpConnection.inl @@ -0,0 +1,126 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + inline void RUdpConnection::Close() + { + m_socket.Close(); + } + + inline void RUdpConnection::Disconnect() + { + Close(); + } + + inline IpAddress RUdpConnection::GetBoundAddress() const + { + return m_socket.GetBoundAddress(); + } + + inline UInt16 RUdpConnection::GetBoundPort() const + { + return m_socket.GetBoundPort(); + } + + inline SocketError RUdpConnection::GetLastError() const + { + return m_lastError; + } + + inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) + { + NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); + + IpAddress any; + switch (protocol) + { + case NetProtocol_Any: + case NetProtocol_Unknown: + NazaraInternalError("Invalid protocol Any at this point"); + return false; + + case NetProtocol_IPv4: + any = IpAddress::AnyIpV4; + break; + + case NetProtocol_IPv6: + any = IpAddress::AnyIpV6; + break; + } + + any.SetPort(port); + return Listen(any, queueSize); + } + + inline void RUdpConnection::SetProtocolId(UInt32 protocolId) + { + m_protocol = protocolId; + } + + inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms) + { + m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling + } + + inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2) + { + unsigned int difference; + if (sequence2 > sequence) + difference = std::numeric_limits::max() - sequence2 + sequence; + else + difference = sequence - sequence2; + + return 0; + } + + inline bool RUdpConnection::HasPendingPackets(PeerData& peer) + { + for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority) + { + std::vector& pendingPackets = peer.pendingPackets[priority]; + if (!pendingPackets.empty()) + return true; + + pendingPackets.clear(); + } + + return false; + } + + inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2) + { + constexpr SequenceIndex maxDifference = std::numeric_limits::max() / 2; + + if (ack > ack2) + return ack - ack2 <= maxDifference; + else if (ack2 > ack) + return ack2 - ack > maxDifference; + else + return false; ///< Same ack + } + + inline bool RUdpConnection::IsReliable(PacketReliability reliability) + { + switch (reliability) + { + case PacketReliability_Reliable: + case PacketReliability_ReliableOrdered: + return true; + + case PacketReliability_Unreliable: + return false; + } + + NazaraError("PacketReliability not handled (0x" + String::Number(reliability, 16) + ')'); + return false; + } +} + +#include diff --git a/include/Nazara/Network/RUdpMessage.hpp b/include/Nazara/Network/RUdpMessage.hpp new file mode 100644 index 000000000..5d4fdb4a5 --- /dev/null +++ b/include/Nazara/Network/RUdpMessage.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RUDMESSAGE_HPP +#define NAZARA_RUDMESSAGE_HPP + +#include +#include +#include + +namespace Nz +{ + struct RUdpMessage + { + IpAddress from; + NetPacket data; + }; +} + +#endif // NAZARA_RUDMESSAGE_HPP \ No newline at end of file diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp index 72fa76517..41868b79b 100644 --- a/src/Nazara/Network/Network.cpp +++ b/src/Nazara/Network/Network.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -55,6 +56,12 @@ namespace Nz return false; } + if (!RUdpConnection::Initialize()) + { + NazaraError("Failed to initialize RUdp"); + return false; + } + onExit.Reset(); NazaraNotice("Initialized: Network module"); @@ -80,6 +87,7 @@ namespace Nz s_moduleReferenceCounter = 0; // Uninitialize module here + RUdpConnection::Uninitialize(); NetPacket::Uninitialize(); SocketImpl::Uninitialize(); diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp new file mode 100644 index 000000000..12fdc3d22 --- /dev/null +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -0,0 +1,482 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +namespace Nz +{ + RUdpConnection::RUdpConnection() : + m_peerIterator(0), + m_forceAckSendTime(10'000), //< 10ms + m_pingInterval(1'000'000), //< 1s + m_protocol(0x4E4E6574), //< "NNet" + m_timeBeforePing(500'000), //< 0.5s + m_timeBeforeTimeOut(10'000'000), //< 10s + m_currentTime(0), + m_shouldAcceptConnections(true) + { + } + + bool RUdpConnection::Connect(const IpAddress& remoteAddress) + { + NazaraAssert(m_socket.GetState() != SocketState_Bound, "Socket must be bound first"); + NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); + NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); + + PeerData& client = RegisterPeer(remoteAddress, PeerState_Connecting); + client.stateData1 = s_randomGenerator(); + + NetPacket connectionRequestPacket(NetCode_RequestConnection); + connectionRequestPacket << client.stateData1; + + EnqueuePacket(client, PacketPriority_Immediate, PacketReliability_Unreliable, connectionRequestPacket); + return true; + } + + bool RUdpConnection::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error) + { + std::vector results = IpAddress::ResolveHostname(protocol, hostName, service, error); + if (results.empty()) + { + m_lastError = SocketError_ResolveError; + return false; + } + + IpAddress hostnameAddress; + for (const HostnameInfo& result : results) + { + if (!result.address) + continue; + + if (result.socketType != SocketType_UDP) + continue; + + hostnameAddress = result.address; + break; //< Take first valid address + } + + return Connect(hostnameAddress); + } + + bool RUdpConnection::Listen(const IpAddress& address, unsigned int queueSize) + { + if (!InitSocket(address.GetProtocol())) + return false; + + return m_socket.Bind(address) == SocketState_Bound; + } + + bool RUdpConnection::PollMessage(RUdpMessage* message) + { + if (m_receivedMessages.empty()) + return false; + + *message = std::move(m_receivedMessages.front()); + m_receivedMessages.pop(); + return true; + } + + bool RUdpConnection::Send(const IpAddress& peerIp, PacketPriority priority, PacketReliability reliability, const NetPacket& packet) + { + auto it = m_peerByIP.find(peerIp); + if (it == m_peerByIP.end()) + return false; /// Silently fail (probably a disconnected client) + + EnqueuePacket(m_peers[it->second], priority, reliability, packet); + return true; + } + + void RUdpConnection::Update() + { + m_currentTime = m_clock.GetMicroseconds(); + + NetPacket receivedPacket; + IpAddress senderIp; + while (m_socket.ReceivePacket(&receivedPacket, &senderIp)) + OnPacketReceived(senderIp, std::move(receivedPacket)); + + //for (unsigned int i = m_activeClients.FindFirst(); i != m_activeClients.npos; i = m_activeClients.FindNext(i)) + //{ + // PeerData& clientData = m_peers[i]; + + CallOnExit resetIterator([this] () { m_peerIterator = m_peers.size(); }); + + for (m_peerIterator = 0; m_peerIterator < m_peers.size(); ++m_peerIterator) + { + PeerData& peer = m_peers[m_peerIterator]; + + UInt32 timeSinceLastPacket = m_currentTime - peer.lastPacketTime; + if (timeSinceLastPacket > m_timeBeforeTimeOut) + { + DisconnectPeer(peer.index); + continue; + } + else if (timeSinceLastPacket > m_timeBeforePing) + { + if (m_currentTime - peer.lastPingTime > m_pingInterval) + { + NetPacket pingPacket(NetCode_Ping); + EnqueuePacket(peer, PacketPriority_Low, PacketReliability_Unreliable, pingPacket); + } + } + + if (peer.state == PeerState_WillAck && m_currentTime - peer.stateData1 > m_forceAckSendTime) + { + NetPacket acknowledgePacket(NetCode_Acknowledge); + EnqueuePacket(peer, PacketPriority_Low, PacketReliability_Reliable, acknowledgePacket); + } + + for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority) + { + std::vector& pendingPackets = peer.pendingPackets[priority]; + for (PendingPacket& packetData : pendingPackets) + SendPacket(peer, std::move(packetData)); + + pendingPackets.clear(); + } + + auto it = peer.pendingAckQueue.begin(); + while (it != peer.pendingAckQueue.end()) + { + if (m_currentTime - it->timeSent > 2 * peer.roundTripTime) + { + OnPacketLost(peer, std::move(*it)); + it = peer.pendingAckQueue.erase(it); + } + else + ++it; + } + } + //m_activeClients.Reset(); + } + + void RUdpConnection::DisconnectPeer(std::size_t peerIndex) + { + PeerData& peer = m_peers[peerIndex]; + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": " + peer.address.ToString() + " has been disconnected due to time-out"); + + OnPeerDisconnected(this, peer.address); + + // Remove from IP lookup table + m_peerByIP.erase(peer.address); + + // Can we safely "remove" this slot? + if (m_peerIterator >= m_peers.size() - 1 || peerIndex > m_peerIterator) + { + // Yes we can + PeerData& newSlot = m_peers[peerIndex]; + newSlot = std::move(m_peers.back()); + newSlot.index = peerIndex; //< Update the moved slot index before resizing (in case it's the last one) + } + else + { + // Nope, let's be tricky + PeerData& current = m_peers[m_peerIterator]; + PeerData& newSlot = m_peers[peerIndex]; + + newSlot = std::move(current); + newSlot.index = peerIndex; //< Update the moved slot index + + current = std::move(m_peers.back()); + current.index = m_peerIterator; //< Update the moved slot index + + --m_peerIterator; + } + + // Pop the last entry (from where we moved our slot) + m_peers.pop_back(); + } + + void RUdpConnection::EnqueuePacket(PeerData& peer, PacketPriority priority, PacketReliability reliability, const NetPacket& packet) + { + UInt16 protocolBegin = static_cast(m_protocol & 0xFFFF); + UInt16 protocolEnd = static_cast((m_protocol & 0xFFFF0000) >> 16); + + NetPacket data(packet.GetNetCode(), MessageHeader + packet.GetDataSize() + MessageFooter); + data << protocolBegin; + + data.GetStream()->SetCursorPos(NetPacket::HeaderSize + MessageHeader); + data.Write(packet.GetConstData() + NetPacket::HeaderSize, packet.GetDataSize()); + + data << protocolEnd; + EnqueuePacketInternal(peer, priority, reliability, std::move(data)); + } + + void RUdpConnection::EnqueuePacketInternal(PeerData& peer, PacketPriority priority, PacketReliability reliability, NetPacket&& data) + { + PendingPacket pendingPacket; + pendingPacket.data = std::move(data); + pendingPacket.priority = priority; + pendingPacket.reliability = reliability; + + peer.pendingPackets[priority].emplace_back(std::move(pendingPacket)); + m_activeClients.UnboundedSet(peer.index); + } + + bool RUdpConnection::InitSocket(NetProtocol protocol) + { + CallOnExit updateLastError([this] + { + m_lastError = m_socket.GetLastError(); + }); + + if (!m_socket.Create(protocol)) + return false; + + m_socket.EnableBlocking(false); + return true; + } + + void RUdpConnection::ProcessAcks(PeerData& peer, SequenceIndex lastAck, UInt32 ackBits) + { + auto it = peer.pendingAckQueue.begin(); + while (it != peer.pendingAckQueue.end()) + { + bool acked = false; + if (lastAck == it->sequenceId) + acked = true; + else if (!IsAckMoreRecent(it->sequenceId, lastAck)) + { + unsigned int difference = ComputeSequenceDifference(lastAck, it->sequenceId); + if (difference <= 32) + acked = (ackBits >> (difference - 1)) & 1; + } + + if (acked) + { + it = peer.pendingAckQueue.erase(it); + } + else + ++it; + } + } + + RUdpConnection::PeerData& RUdpConnection::RegisterPeer(const IpAddress& address, PeerState state) + { + PeerData data; + data.address = address; + data.localSequence = 0; + data.remoteSequence = 0; + data.index = m_peers.size(); + data.lastPacketTime = m_currentTime; + data.lastPingTime = m_currentTime; + data.roundTripTime = 1000000; ///< Okay that's quite a lot + data.state = state; + + m_activeClients.UnboundedSet(data.index); + m_peerByIP[address] = data.index; + + m_peers.emplace_back(std::move(data)); + return m_peers.back(); + } + + void RUdpConnection::OnClientRequestingConnection(const IpAddress& address, SequenceIndex sequenceId, UInt64 token) + { + // Call hook to check if client should be accepted or not + OnPeerConnection(this, address); + + PeerData& client = RegisterPeer(address, PeerState_Aknowledged); + client.remoteSequence = sequenceId; + + /// Acknowledge connection + NetPacket connectionAcceptedPacket(NetCode_AcknowledgeConnection); + //connectionAcceptedPacket << address; + connectionAcceptedPacket << ~token; + + EnqueuePacket(client, PacketPriority_Immediate, PacketReliability_Reliable, connectionAcceptedPacket); + } + + void RUdpConnection::OnPacketLost(PeerData& peer, PendingAckPacket&& packet) + { + //NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Lost packet " + String::Number(packet.sequenceId)); + + if (IsReliable(packet.reliability)) + EnqueuePacketInternal(peer, packet.priority, packet.reliability, std::move(packet.data)); + } + + void RUdpConnection::OnPacketReceived(const IpAddress& peerIp, NetPacket&& packet) + { + UInt16 protocolBegin; + UInt16 protocolEnd; + SequenceIndex sequenceId; + SequenceIndex lastAck; + UInt32 ackBits; + + packet.GetStream()->SetCursorPos(packet.GetSize() - MessageFooter); + packet >> protocolEnd; + + packet.GetStream()->SetCursorPos(NetPacket::HeaderSize); + packet >> protocolBegin; + + UInt32 protocolId = static_cast(protocolEnd) << 16 | protocolBegin; + if (protocolId != m_protocol) + return; ///< Ignore + + packet >> sequenceId >> lastAck >> ackBits; + + auto it = m_peerByIP.find(peerIp); + if (it == m_peerByIP.end()) + { + switch (packet.GetNetCode()) + { + case NetCode_RequestConnection: + { + UInt64 token; + packet >> token; + + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Received NetCode_RequestConnection from " + peerIp.ToString() + ": " + String::Number(token)); + if (!m_shouldAcceptConnections) + return; //< Ignore + + OnClientRequestingConnection(peerIp, sequenceId, token); + break; + } + + default: + return; //< Ignore + } + } + else + { + PeerData& peer = m_peers[it->second]; + peer.lastPacketTime = m_currentTime; + + if (peer.receivedQueue.find(sequenceId) != peer.receivedQueue.end()) + return; //< Ignore + + ///< Receiving a packet from an acknowledged client means the connection works in both ways + if (peer.state == PeerState_Aknowledged && packet.GetNetCode() != NetCode_RequestConnection) + { + peer.state = PeerState_Connected; + OnPeerAcknowledged(this, peerIp); + } + + if (IsAckMoreRecent(sequenceId, peer.remoteSequence)) + peer.remoteSequence = sequenceId; + + ProcessAcks(peer, lastAck, ackBits); + + peer.receivedQueue.insert(sequenceId); + + switch (packet.GetNetCode()) + { + case NetCode_Acknowledge: + return; //< Do not switch to will ack mode (to prevent infinite replies, just let's ping/pong do that) + + case NetCode_AcknowledgeConnection: + { + if (peer.state == PeerState_Connected) + break; + + IpAddress externalAddress; + UInt64 token; + packet /*>> externalAddress*/ >> token; + + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Received NetCode_AcknowledgeConnection from " + peerIp.ToString() + ": " + String::Number(token)); + if (token == ~peer.stateData1) + { + peer.state = PeerState_Connected; + OnConnectedToPeer(this); + } + else + { + NazaraNotice("Received wrong token (" + String::Number(token) + " instead of " + String::Number(~peer.stateData1) + ") from client " + peer.address); + return; //< Ignore + } + + break; + } + + case NetCode_RequestConnection: + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Received NetCode_RequestConnection from " + peerIp.ToString()); + return; //< Ignore + + case NetCode_Ping: + { + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Received NetCode_Ping from " + peerIp.ToString()); + + NetPacket pongPacket(NetCode_Pong); + EnqueuePacket(peer, PacketPriority_Low, PacketReliability_Unreliable, pongPacket); + break; + } + + case NetCode_Pong: + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Received NetCode_Pong from " + peerIp.ToString()); + break; + + default: + { + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Received 0x" + String::Number(packet.GetNetCode(), 16) + " from " + peerIp.ToString()); + RUdpMessage receivedMessage; + receivedMessage.from = peerIp; + receivedMessage.data = std::move(packet); + + m_receivedMessages.emplace(std::move(receivedMessage)); + break; + } + } + + if (!HasPendingPackets(peer)) + { + peer.state = PeerState_WillAck; + peer.stateData1 = m_currentTime; + } + } + } + + void RUdpConnection::SendPacket(PeerData& peer, PendingPacket&& packet) + { + if (peer.state == PeerState_WillAck) + peer.state = PeerState_Connected; + + SequenceIndex remoteSequence = peer.remoteSequence; + + UInt32 previousAcks = 0; + for (SequenceIndex ack : peer.receivedQueue) + { + if (ack == remoteSequence) + continue; + + unsigned int difference = ComputeSequenceDifference(remoteSequence, ack); + if (difference <= 32U) + previousAcks |= (1U << (difference - 1)); + } + + SequenceIndex sequenceId = ++peer.localSequence; + + packet.data.GetStream()->SetCursorPos(NetPacket::HeaderSize + sizeof(UInt16)); ///< Protocol begin has already been filled + packet.data << sequenceId; + packet.data << remoteSequence; + packet.data << previousAcks; + + m_socket.SendPacket(peer.address, packet.data); + + PendingAckPacket pendingAckPacket; + pendingAckPacket.data = std::move(packet.data); + pendingAckPacket.priority = packet.priority; + pendingAckPacket.reliability = packet.reliability; + pendingAckPacket.sequenceId = sequenceId; + pendingAckPacket.timeSent = m_currentTime; + + peer.pendingAckQueue.emplace_back(std::move(pendingAckPacket)); + } + + bool RUdpConnection::Initialize() + { + std::random_device device; + s_randomGenerator.seed(device()); + + return true; + } + + inline void RUdpConnection::Uninitialize() + { + } + + std::mt19937_64 RUdpConnection::s_randomGenerator; +} From 83884015fc1ed68c079036ecfdec2ee82e04b3f7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 15 Mar 2016 23:00:03 +0100 Subject: [PATCH 164/229] Add current work Former-commit-id: 06dd34f00951e334b330c067f61f69fc73dcc2d2 --- SDK/include/NDK/Application.hpp | 32 ++++++++++++++++++++++++ SDK/include/NDK/Application.inl | 38 +++++++++++++++++++++++++++- SDK/src/NDK/Application.cpp | 44 +++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index 9b6eedae1..644dcc971 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -8,6 +8,10 @@ #define NDK_APPLICATION_HPP #include +#include +#include +#include +#include namespace Ndk { @@ -15,7 +19,35 @@ namespace Ndk { public: inline Application(); + Application(const Application&) = delete; inline ~Application(); + + #ifndef NDK_SERVER + template T& AddWindow(Args&&... args); + #endif + template World& AddWorld(Args&&... args); + + bool Run(); + + inline void Quit(); + + Application& operator=(const Application&) = delete; + + inline static Application* Instance(); + + private: + #ifndef NDK_SERVER + std::vector> m_windows; + #endif + std::vector m_worlds; + Nz::Clock m_updateClock; + #ifndef NDK_SERVER + bool m_exitOnClosedWindows; + #endif + bool m_shouldQuit; + float m_updateTime; + + static Application* s_application; }; } diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index dafbd54d8..690cf54d3 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -3,12 +3,21 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include #include namespace Ndk { - inline Application::Application() + inline Application::Application() : + #ifndef NDK_SERVER + m_exitOnClosedWindows(true), + #endif + m_shouldQuit(false), + m_updateTime(0.f) { + NazaraAssert(s_application == nullptr, "You can create only one application instance per program"); + s_application = this; + Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true); // Initialisation du SDK @@ -21,5 +30,32 @@ namespace Ndk Sdk::Uninitialize(); // Libération automatique des modules + s_application = nullptr; + } + + template + T& Application::AddWindow(Args&&... args) + { + static_assert(std::is_base_of::value, "Type must inherit Window"); + + m_windows.emplace_back(new T(std::forward(args)...)); + return static_cast(*m_windows.back().get()); + } + + template + World& Application::AddWorld(Args&&... args) + { + m_worlds.emplace_back(std::forward(args)...); + return *m_worlds.back(); + } + + inline void Application::Quit() + { + m_shouldQuit = true; + } + + inline Application* Application::Instance() + { + return s_application; } } diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index a2141b0f8..e15ba2f92 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -3,3 +3,47 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include + +namespace Ndk +{ + bool Application::Run() + { + #ifndef NDK_SERVER + bool hasAtLeastOneActiveWindow = false; + + auto it = m_windows.begin(); + while (it != m_windows.end()) + { + Nz::Window& window = **it; + + if (!window.IsOpen(true)) + { + it = m_windows.erase(it); + continue; + } + + hasAtLeastOneActiveWindow = true; + + ++it; + } + #endif + + float elapsedTime = m_updateClock.GetSeconds(); + m_updateClock.Restart(); + + for (World& world : m_worlds) + world.Update(elapsedTime); + + if (m_shouldQuit) + return false; + + #ifndef NDK_SERVER + if (m_exitOnClosedWindows && !hasAtLeastOneActiveWindow) + return false; + #endif + + return true; + } + + Application* Application::s_application = nullptr; +} \ No newline at end of file From d2e3bb36a640bff91d90ad55992f9650c6f19943 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 15 Mar 2016 23:00:58 +0100 Subject: [PATCH 165/229] Alphabetical commit Former-commit-id: 4277d1fdc84af2031faa826520fcc442edb47a10 --- include/Nazara/Core/Error.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index b210c2e1d..b71bc8cf3 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -8,9 +8,9 @@ #define NAZARA_ERROR_HPP #include +#include #include #include -#include #include #if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG) From 42874b90d93e245230a3d911ee19af920dc04296 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 19 Mar 2016 12:21:07 +0100 Subject: [PATCH 166/229] SDK: Add StateMachine (FSM) Former-commit-id: 8029f7cce71809ff1f661982d39750c48c86431f --- SDK/include/NDK/State.hpp | 28 +++++++++++++++++++++++ SDK/include/NDK/StateMachine.hpp | 39 ++++++++++++++++++++++++++++++++ SDK/include/NDK/StateMachine.inl | 26 +++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 SDK/include/NDK/State.hpp create mode 100644 SDK/include/NDK/StateMachine.hpp create mode 100644 SDK/include/NDK/StateMachine.inl diff --git a/SDK/include/NDK/State.hpp b/SDK/include/NDK/State.hpp new file mode 100644 index 000000000..0a113def3 --- /dev/null +++ b/SDK/include/NDK/State.hpp @@ -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 + +#pragma once + +#ifndef NDK_STATE_HPP +#define NDK_STATE_HPP + +#include + +namespace Ndk +{ + class StateMachine; + + class State + { + public: + State(); + ~State(); + + virtual void Enter(StateMachine& fsm) = 0; + virtual void Leave(StateMachine& fsm) = 0; + virtual bool Update(StateMachine& fsm, float elapsedTime) = 0; + }; +} + +#endif // NDK_STATE_HPP \ No newline at end of file diff --git a/SDK/include/NDK/StateMachine.hpp b/SDK/include/NDK/StateMachine.hpp new file mode 100644 index 000000000..8d05f8335 --- /dev/null +++ b/SDK/include/NDK/StateMachine.hpp @@ -0,0 +1,39 @@ +// 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_STATEMACHINE_HPP +#define NDK_STATEMACHINE_HPP + +#include +#include +#include + +namespace Ndk +{ + class StateMachine + { + public: + inline StateMachine(); + StateMachine(const StateMachine&) = delete; + inline StateMachine(StateMachine&& fsm) = default; + inline ~StateMachine(); + + inline void ChangeState(std::shared_ptr state); + + inline bool Update(float elapsedTime); + + inline StateMachine& operator=(StateMachine&& fsm) = default; + StateMachine& operator=(const StateMachine&) = delete; + + private: + std::shared_ptr m_currentState; + std::shared_ptr m_nextState; + }; +} + +#include + +#endif // NDK_STATEMACHINE_HPP \ No newline at end of file diff --git a/SDK/include/NDK/StateMachine.inl b/SDK/include/NDK/StateMachine.inl new file mode 100644 index 000000000..0a1e195c4 --- /dev/null +++ b/SDK/include/NDK/StateMachine.inl @@ -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 +#include + +namespace Ndk +{ + inline void StateMachine::ChangeState(std::shared_ptr state) + { + m_nextState = std::move(state); + } + + inline bool StateMachine::Update(float elapsedTime) + { + if (m_nextState) + { + m_currentState->Leave(*this); + m_currentState = std::move(m_nextState); + m_currentState->Enter(*this); + } + + return m_currentState->Update(*this, elapsedTime); + } +} From 8aa406a310398ec7b46abae2e6747e479ad4b336 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 19 Mar 2016 14:20:28 +0100 Subject: [PATCH 167/229] Sdk/Application: Fix AddWorld Former-commit-id: 8b4758f0fafd6aae0360d0c87b8d5362e8e8d583 --- SDK/include/NDK/Application.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index 690cf54d3..1efd10bd4 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -46,7 +46,7 @@ namespace Ndk World& Application::AddWorld(Args&&... args) { m_worlds.emplace_back(std::forward(args)...); - return *m_worlds.back(); + return m_worlds.back(); } inline void Application::Quit() From 8d6c8e8a79f7357f6b7cfa266cb4f7efb256ddaf Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 19 Mar 2016 14:20:55 +0100 Subject: [PATCH 168/229] Sdk/Application: Fix errors while exiting Former-commit-id: 5b22aad341730918fbe4f56698a6a10e251256af --- SDK/include/NDK/Application.inl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index 1efd10bd4..ca1fa1ffb 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -26,6 +26,11 @@ namespace Ndk inline Application::~Application() { + m_worlds.clear(); + #ifndef NDK_SERVER + m_windows.clear(); + #endif + // Libération du SDK Sdk::Uninitialize(); From 11fe78f7e08194d3d4e4335e0f96b0add4da5e85 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 25 Mar 2016 21:34:17 +0100 Subject: [PATCH 169/229] Ndk/StateMachine: Add constructor/destructor, should be usable now Former-commit-id: fab76ba97470e8d7a2f4a01a9d1746a8e213892f --- SDK/include/NDK/StateMachine.hpp | 2 +- SDK/include/NDK/StateMachine.inl | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/StateMachine.hpp b/SDK/include/NDK/StateMachine.hpp index 8d05f8335..8e7ad2f64 100644 --- a/SDK/include/NDK/StateMachine.hpp +++ b/SDK/include/NDK/StateMachine.hpp @@ -16,7 +16,7 @@ namespace Ndk class StateMachine { public: - inline StateMachine(); + inline StateMachine(std::shared_ptr originalState); StateMachine(const StateMachine&) = delete; inline StateMachine(StateMachine&& fsm) = default; inline ~StateMachine(); diff --git a/SDK/include/NDK/StateMachine.inl b/SDK/include/NDK/StateMachine.inl index 0a1e195c4..208a609a3 100644 --- a/SDK/include/NDK/StateMachine.inl +++ b/SDK/include/NDK/StateMachine.inl @@ -2,11 +2,24 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include #include namespace Ndk { + inline StateMachine::StateMachine(std::shared_ptr originalState) : + m_currentState(std::move(originalState)) + { + NazaraAssert(m_currentState, "StateMachine must have a state to begin with"); + } + + inline StateMachine::~StateMachine() + { + m_currentState->Leave(*this); + } + + inline void StateMachine::ChangeState(std::shared_ptr state) { m_nextState = std::move(state); From b28ab414c9c91ccacc8e48b28531c538011869cc Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 25 Mar 2016 23:07:59 +0100 Subject: [PATCH 170/229] Math/BoundingVolume: Add ExtendTo method Former-commit-id: 5cfd681d5cd7adcc2bcf16184a2da821bf4eb477 --- include/Nazara/Math/BoundingVolume.hpp | 2 ++ include/Nazara/Math/BoundingVolume.inl | 46 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index 60a16c260..6f1f4b804 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -30,6 +30,8 @@ namespace Nz BoundingVolume(const BoundingVolume& volume) = default; ~BoundingVolume() = default; + BoundingVolume& ExtendTo(const BoundingVolume& volume); + bool IsFinite() const; bool IsInfinite() const; bool IsNull() const; diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 03e6476bc..ac03268ed 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -124,6 +124,52 @@ namespace Nz Set(volume); } + + /*! + * \brief Extends the bounding volume to contain another bounding volume + * \return A reference to the the bounding volume + * + * \param volume Other volume to contain + * + * \remark Extending to a null bounding volume has no effect while extending to a infinite bounding volume will set it as infinite + */ + template + BoundingVolume& BoundingVolume::BoundingVolume::ExtendTo(const BoundingVolume& volume) + { + switch (extend) + { + case Extend_Finite: + { + switch (volume.extend) + { + case Extend_Finite: + { + // Extend the OBB local box + obb.localBox.ExtendTo(volume.localBox); + break; + } + + case Extend_Infinite: + MakeInfinite(); + break; + + case Extend_Null: + break; + } + break; + } + + case Extend_Infinite: + break; //< We already contain the bounding volume + + case Extend_Null: + Set(volume); + break; + } + + return *this; + } + /*! * \brief Checks whether the volume is finite * \return true if extend is Extend_Finite From 2b9dcb47c05b223c436add06a059f35898bb6c20 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 26 Mar 2016 01:38:03 +0100 Subject: [PATCH 171/229] Math/BoundingVolume: Fix compilation Former-commit-id: 6717a9d8d92f05ba3e4ae3b088aef79f0a637736 --- include/Nazara/Math/BoundingVolume.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index ac03268ed..15107e755 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -134,7 +134,7 @@ namespace Nz * \remark Extending to a null bounding volume has no effect while extending to a infinite bounding volume will set it as infinite */ template - BoundingVolume& BoundingVolume::BoundingVolume::ExtendTo(const BoundingVolume& volume) + BoundingVolume& BoundingVolume::ExtendTo(const BoundingVolume& volume) { switch (extend) { @@ -145,7 +145,7 @@ namespace Nz case Extend_Finite: { // Extend the OBB local box - obb.localBox.ExtendTo(volume.localBox); + obb.localBox.ExtendTo(volume.obb.localBox); break; } From dd87b9b1157f949e4a97c5a62ea6ac073c739fe2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 26 Mar 2016 01:38:30 +0100 Subject: [PATCH 172/229] Ndk/GraphicsComponent: Add BoundingVolume Former-commit-id: e053b21e5495e097a752c17bf2f9367f55b78d78 --- .../NDK/Components/GraphicsComponent.hpp | 7 ++++++ .../NDK/Components/GraphicsComponent.inl | 23 +++++++++++++++++++ SDK/src/NDK/Components/GraphicsComponent.cpp | 12 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 4a3ee80c9..4a32f90e5 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -26,11 +26,15 @@ namespace Ndk inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); + inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; + inline const Nz::BoundingVolumef& GetBoundingVolume() const; + static ComponentIndex componentIndex; private: + inline void InvalidateBoundingVolume(); void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index); inline void InvalidateRenderables(); inline void InvalidateTransformMatrix(); @@ -41,6 +45,7 @@ namespace Ndk void OnDetached() override; void OnNodeInvalidated(const Nz::Node* node); + void UpdateBoundingVolume() const; void UpdateTransformMatrix() const; NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot); @@ -61,7 +66,9 @@ namespace Ndk }; std::vector m_renderables; + mutable Nz::BoundingVolumef m_boundingVolume; mutable Nz::Matrix4f m_transformMatrix; + mutable bool m_boundingVolumeUpdated; mutable bool m_transformMatrixUpdated; }; } diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index b51bf94f7..205eb9462 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -8,7 +8,9 @@ namespace Ndk { inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) : Component(graphicsComponent), + m_boundingVolume(graphicsComponent.m_boundingVolume), m_transformMatrix(graphicsComponent.m_transformMatrix), + m_boundingVolumeUpdated(graphicsComponent.m_boundingVolumeUpdated), m_transformMatrixUpdated(graphicsComponent.m_transformMatrixUpdated) { m_renderables.reserve(graphicsComponent.m_renderables.size()); @@ -39,6 +41,14 @@ namespace Ndk r.data.renderOrder = renderOrder; r.renderable = std::move(renderable); r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1)); + + InvalidateBoundingVolume(); + } + + inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const + { + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); } inline void GraphicsComponent::EnsureTransformMatrixUpdate() const @@ -47,6 +57,18 @@ namespace Ndk UpdateTransformMatrix(); } + inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const + { + EnsureBoundingVolumeUpdate(); + + return m_boundingVolume; + } + + inline void GraphicsComponent::InvalidateBoundingVolume() + { + m_boundingVolumeUpdated = false; + } + inline void GraphicsComponent::InvalidateRenderables() { for (Renderable& r : m_renderables) @@ -55,6 +77,7 @@ namespace Ndk inline void GraphicsComponent::InvalidateTransformMatrix() { + m_boundingVolumeUpdated = false; m_transformMatrixUpdated = false; InvalidateRenderables(); diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 566724350..e345bdb85 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -63,6 +63,18 @@ namespace Ndk InvalidateTransformMatrix(); } + void GraphicsComponent::UpdateBoundingVolume() const + { + EnsureTransformMatrixUpdate(); + + m_boundingVolume.MakeNull(); + for (const Renderable& r : m_renderables) + m_boundingVolume.ExtendTo(r.renderable->GetBoundingVolume()); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; + } + void GraphicsComponent::UpdateTransformMatrix() const { NazaraAssert(m_entity && m_entity->HasComponent(), "GraphicsComponent requires NodeComponent"); From 8ae493b53550ebb07cbb01099100c8d5392a1bff Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 29 Mar 2016 23:42:25 +0200 Subject: [PATCH 173/229] Ndk/StateMachine: Fix constructor not calling State::Enter Former-commit-id: 8e66600c19c53617cab1d889d8fa3c219bc9ea19 --- SDK/include/NDK/StateMachine.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/SDK/include/NDK/StateMachine.inl b/SDK/include/NDK/StateMachine.inl index 208a609a3..fc4c7f787 100644 --- a/SDK/include/NDK/StateMachine.inl +++ b/SDK/include/NDK/StateMachine.inl @@ -12,6 +12,7 @@ namespace Ndk m_currentState(std::move(originalState)) { NazaraAssert(m_currentState, "StateMachine must have a state to begin with"); + m_currentState->Enter(*this); } inline StateMachine::~StateMachine() From 5465951f8738f3af7486a513ba8e546d04a0da85 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 17:49:27 +0200 Subject: [PATCH 174/229] Core/ResourceLoader: Fix assert Former-commit-id: 391a0ec4de1a1c5ed97ea82aee0d3d69fbbc00df --- include/Nazara/Core/ResourceLoader.inl | 2 +- src/Nazara/Core/String.cpp | 58 +++++++++++++++----------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 3661de08d..af0a8a7f0 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -244,7 +244,7 @@ namespace Nz bool ResourceLoader::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters) { NazaraAssert(resource, "Invalid resource"); - NazaraAssert(stream.GetCursorPos() >= stream.GetSize(), "No data to load"); + NazaraAssert(stream.GetCursorPos() < stream.GetSize(), "No data to load"); NazaraAssert(parameters.IsValid(), "Invalid parameters"); UInt64 streamPos = stream.GetCursorPos(); diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index acbafbd5c..3e72e1dce 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -1462,8 +1462,12 @@ namespace Nz { if (Detail::ToLower(*ptr) == c) { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; + if (ptr != m_sharedString->string.get()) + { + --ptr; + if (!(Unicode::GetCategory(*ptr++) & Unicode::Category_Separator)) + continue; + } const char* p = &string[1]; const char* tPtr = ptr+1; @@ -1471,7 +1475,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || std::isspace(*tPtr)) + if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) return ptr-m_sharedString->string.get(); else break; @@ -1496,8 +1500,12 @@ namespace Nz { if (*ptr == string[0]) { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; + if (ptr != m_sharedString->string.get()) + { + --ptr; + if (!(Unicode::GetCategory(*ptr++) & Unicode::Category_Separator)) + continue; + } const char* p = &string[1]; const char* tPtr = ptr+1; @@ -1505,7 +1513,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || std::isspace(*tPtr)) + if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) return ptr-m_sharedString->string.get(); else break; @@ -1655,7 +1663,8 @@ namespace Nz { if (Detail::ToLower(*ptr) == c) { - if (*(ptr+1) != '\0' && !std::isspace(*(ptr+1))) + char nextC = *(ptr + 1); + if (nextC != '\0' && (Unicode::GetCategory(nextC) & Unicode::Category_Separator_Space) == 0) continue; const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; @@ -1666,7 +1675,7 @@ namespace Nz if (p == &string.m_sharedString->string[0]) { - if (ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) + if (ptr == m_sharedString->string.get() || Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator_Space) return ptr-m_sharedString->string.get(); else break; @@ -1685,7 +1694,8 @@ namespace Nz { if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) { - if (*(ptr+1) != '\0' && !std::isspace(*(ptr+1))) + char nextC = *(ptr + 1); + if (nextC != '\0' && (Unicode::GetCategory(nextC) & Unicode::Category_Separator_Space) == 0) continue; const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; @@ -1696,7 +1706,7 @@ namespace Nz if (p == &string.m_sharedString->string[0]) { - if (ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) + if (ptr == m_sharedString->string.get() || Unicode::GetCategory(*(ptr - 1)) & Unicode::Category_Separator_Space) return ptr-m_sharedString->string.get(); else break; @@ -1834,7 +1844,7 @@ namespace Nz { if (Detail::ToLower(*ptr) == c) { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + if (ptr != m_sharedString->string.get() && (Unicode::GetCategory(*(ptr - 1)) & Unicode::Category_Separator) == 0) continue; const char* p = &string[1]; @@ -1843,7 +1853,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || std::isspace(*tPtr)) + if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) return ptr - m_sharedString->string.get(); else break; @@ -1865,7 +1875,7 @@ namespace Nz { if (*ptr == string[0]) { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + if (ptr != m_sharedString->string.get() && (Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator) == 0) continue; const char* p = &string[1]; @@ -1874,7 +1884,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || std::isspace(*tPtr)) + if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) return ptr - m_sharedString->string.get(); else break; @@ -2016,7 +2026,7 @@ namespace Nz { if (Detail::ToLower(*ptr) == c) { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + if (ptr != m_sharedString->string.get() && (Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator_Space) == 0) continue; const char* p = &string.m_sharedString->string[1]; @@ -2025,7 +2035,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || std::isspace(*tPtr)) + if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator_Space) return ptr - m_sharedString->string.get(); else break; @@ -2046,7 +2056,7 @@ namespace Nz while ((ptr = std::strstr(ptr, string.GetConstBuffer())) != nullptr) { // If the word is really alone - if ((ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || std::isspace(*(ptr+m_sharedString->size)))) + if ((ptr == m_sharedString->string.get() || Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator_Space) && (*(ptr+m_sharedString->size) == '\0' || Unicode::GetCategory(*(ptr+m_sharedString->size)) & Unicode::Category_Separator_Space)) return ptr - m_sharedString->string.get(); ptr++; @@ -2221,7 +2231,7 @@ namespace Nz { do { - if (std::isspace(*ptr)) + if (Unicode::GetCategory(*ptr) & Unicode::Category_Separator) { endPos = static_cast(ptr - m_sharedString->string.get() - 1); break; @@ -2273,7 +2283,7 @@ namespace Nz { do { - if (std::isspace(*ptr)) + if (Unicode::GetCategory(*ptr) & Unicode::Category_Separator) inWord = false; else { @@ -3427,7 +3437,7 @@ namespace Nz const char* limit = &m_sharedString->string[m_sharedString->size]; do { - if (std::isspace(*ptr)) + if (Unicode::GetCategory(*ptr) & Unicode::Category_Separator) { if (inword) { @@ -4232,7 +4242,7 @@ namespace Nz utf8::unchecked::iterator it(m_sharedString->string.get()); do { - if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + if ((Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) break; } while (*++it); @@ -4247,7 +4257,7 @@ namespace Nz utf8::unchecked::iterator it(&m_sharedString->string[m_sharedString->size]); while ((it--).base() != m_sharedString->string.get()) { - if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + if ((Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) break; } @@ -4263,7 +4273,7 @@ namespace Nz { for (; startPos < m_sharedString->size; ++startPos) { - if (!std::isspace(m_sharedString->string[startPos])) + if ((Unicode::GetCategory(m_sharedString->string[startPos]) & Unicode::Category_Separator) == 0) break; } } @@ -4273,7 +4283,7 @@ namespace Nz { for (; endPos > 0; --endPos) { - if (!std::isspace(m_sharedString->string[endPos])) + if ((Unicode::GetCategory(m_sharedString->string[endPos]) & Unicode::Category_Separator) == 0) break; } } From cc9aec3a5230346cea2b43121a1b9397cb9a91ea Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 17:50:26 +0200 Subject: [PATCH 175/229] Core/HardwareInfo: Fix comments Former-commit-id: 48afaf7a2bb258e65fdd4569601edef2031a241f --- src/Nazara/Core/HardwareInfo.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index 1fbd1a04a..baef7c2f3 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -212,9 +212,9 @@ namespace Nz s_initialized = true; - UInt32 registers[4]; // Get the four registers (EAX, EBX, ECX et EDX) + UInt32 registers[4]; // To store our registers values (EAX, EBX, ECX and EDX) - // To make it more clear + // Let's make it clearer UInt32& eax = registers[0]; UInt32& ebx = registers[1]; UInt32& ecx = registers[2]; @@ -223,7 +223,7 @@ namespace Nz // To begin, we get the id of the constructor and the id of maximal functions supported by the CPUID HardwareInfoImpl::Cpuid(0, 0, registers); - // Watchout to the order : EBX, EDX, ECX + // Note the order: EBX, EDX, ECX UInt32 manufacturerId[3] = {ebx, edx, ecx}; // Identification of conceptor @@ -239,7 +239,7 @@ namespace Nz if (eax >= 1) { - // Recuperation of certain capacities of the processor (ECX et EDX, function 1) + // Retrieval of certain capacities of the processor (ECX et EDX, function 1) HardwareInfoImpl::Cpuid(1, 0, registers); s_capabilities[ProcessorCap_AVX] = (ecx & (1U << 28)) != 0; @@ -253,23 +253,23 @@ namespace Nz s_capabilities[ProcessorCap_SSE42] = (ecx & (1U << 20)) != 0; } - // Recuperation of biggest extended function handled (EAX, fonction 0x80000000) + // Retrieval of biggest extended function handled (EAX, function 0x80000000) HardwareInfoImpl::Cpuid(0x80000000, 0, registers); UInt32 maxSupportedExtendedFunction = eax; if (maxSupportedExtendedFunction >= 0x80000001) { - // Recuperation of extended capabilities of the processor (ECX et EDX, fonction 0x80000001) + // Retrieval of extended capabilities of the processor (ECX and EDX, function 0x80000001) HardwareInfoImpl::Cpuid(0x80000001, 0, registers); - s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support of 64bits, independant of the OS + s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support of 64bits, independent of the OS s_capabilities[ProcessorCap_FMA4] = (ecx & (1U << 16)) != 0; s_capabilities[ProcessorCap_SSE4a] = (ecx & (1U << 6)) != 0; s_capabilities[ProcessorCap_XOP] = (ecx & (1U << 11)) != 0; if (maxSupportedExtendedFunction >= 0x80000004) { - // Recuperation of the string describing the processor (EAX, EBX, ECX et EDX, + // Retrieval of the string describing the processor (EAX, EBX, ECX and EDX, // functions from 0x80000002 to 0x80000004 inclusive) char* ptr = &s_brandString[0]; for (UInt32 code = 0x80000002; code <= 0x80000004; ++code) @@ -280,7 +280,7 @@ namespace Nz ptr += 4*sizeof(UInt32); } - // The character '\0' is already returned + // The character '\0' is already part of the string } } From 308b297a463595a63fd13edb29e9beaf225eab88 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 17:50:48 +0200 Subject: [PATCH 176/229] Lua/LuaInstance: Set SetTable as const Former-commit-id: d480e243ddaf6fb6a016fde9ad9642b82e4703fe --- include/Nazara/Lua/LuaInstance.hpp | 2 +- src/Nazara/Lua/LuaInstance.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index f60898e66..9dd5c3571 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -158,7 +158,7 @@ namespace Nz void SetMetatable(const String& tname) const; void SetMetatable(int index) const; void SetMemoryLimit(UInt32 memoryLimit); - void SetTable(int index = -3); + void SetTable(int index = -3) const; void SetTimeLimit(UInt32 timeLimit); bool ToBoolean(int index) const; diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 3a1880681..c6b6a45e5 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -754,7 +754,7 @@ namespace Nz m_memoryLimit = memoryLimit; } - void LuaInstance::SetTable(int index) + void LuaInstance::SetTable(int index) const { lua_settable(m_state, index); } From a8303d8d2456ff31f01caa7cad248a954e5052e4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:05:11 +0200 Subject: [PATCH 177/229] Lua/LuaInstance: Fix enum querying Former-commit-id: 7fa25a981425694108767ce3a9b56b8e155476a4 --- include/Nazara/Lua/LuaInstance.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index bea66215c..7ae8a7a88 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -87,7 +87,7 @@ namespace Nz } template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) + std::enable_if_t::value && !std::is_enum::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { if (instance.IsValid(index)) return LuaImplQueryArg(instance, index, arg, tag); From bf288e7f0601a2da229f4275318ad1bad724382e Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:05:28 +0200 Subject: [PATCH 178/229] Lua/LuaInstance: Fix crash with invalid objects Former-commit-id: 398ce80f268308489637c237245dae0ec40366b9 --- include/Nazara/Lua/LuaInstance.inl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 7ae8a7a88..32103afe3 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -329,6 +329,12 @@ namespace Nz { NazaraUnused(instance); + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + Apply(*object, func, m_args); return 0; } @@ -336,6 +342,12 @@ namespace Nz template std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } @@ -344,6 +356,12 @@ namespace Nz { NazaraUnused(instance); + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + Apply(*object, func, m_args); return 0; } @@ -351,6 +369,12 @@ namespace Nz template std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } From 9390ce35b3073b6441b9df4f2ca2cb70666ed98a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:06:18 +0200 Subject: [PATCH 179/229] Lua/LuaInstance: Add automatic conversion of std::vector Former-commit-id: 31b32f9c4b9ccd825f2d08ea8499211040a0b9ab --- include/Nazara/Lua/LuaInstance.inl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 32103afe3..685c50719 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace Nz @@ -149,6 +150,25 @@ namespace Nz return 1; } + template + inline int LuaImplReplyVal(const LuaInstance& instance, std::vector valContainer, TypeTag>) + { + std::size_t index = 1; + instance.PushTable(valContainer.size()); + for (const T& val : valContainer) + { + instance.PushInteger(index++); + if (LuaImplReplyVal(instance, val, TypeTag()) != 1) + { + instance.Error("Couldn't create table: type need more than one place to store"); + return 0; + } + instance.SetTable(); + } + + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, ByteArray val, TypeTag) { instance.PushString(reinterpret_cast(val.GetConstBuffer()), val.GetSize()); From b6ea30f9c180d69520ac0ee6a3b565956553a618 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:15:17 +0200 Subject: [PATCH 180/229] Lua/LuaClass: Add a default ToString implementation Former-commit-id: ff6c9cf1d18d34ad8fd7b03c970eec2da5ba0947 --- include/Nazara/Lua/LuaClass.hpp | 1 + include/Nazara/Lua/LuaClass.inl | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index b4aa9d87b..130ac2904 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -86,6 +86,7 @@ namespace Nz static int StaticGetterProxy(lua_State* state); static int StaticMethodProxy(lua_State* state); static int StaticSetterProxy(lua_State* state); + static int ToStringProxy(lua_State* state); std::map m_methods; std::map m_staticMethods; diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index b2bbdbc3e..393225399 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -64,6 +64,15 @@ namespace Nz lua.PushString(m_info->name); lua.SetField("__type"); + // In case a __tostring method is missing, add a default implementation returning the type + if (m_methods.find("__tostring") == m_methods.end()) + { + // Define the Finalizer + lua.PushValue(1); // shared_ptr on UserData + lua.PushCFunction(ToStringProxy, 1); + lua.SetField("__tostring"); + } + // Define the Finalizer lua.PushValue(1); lua.PushCFunction(FinalizerProxy, 1); @@ -486,6 +495,17 @@ namespace Nz return 1; } + + template + int LuaClass::ToStringProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + + lua.PushString(info->name); + return 1; + } } #include From b331d66c7077930893b23896699d6213852463a9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:16:05 +0200 Subject: [PATCH 181/229] Lua/LuaClass: Add possibility to set up a custom converter Former-commit-id: 96cf62a16845b5cf44d5724bfd3b9e5b7672ad03 --- include/Nazara/Lua/LuaClass.hpp | 9 ++++---- include/Nazara/Lua/LuaClass.inl | 40 +++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 130ac2904..eb4cb51e3 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -29,14 +29,15 @@ namespace Nz using ClassFunc = std::function; using ClassIndexFunc = std::function; using ConstructorFunc = std::function; + template using ConvertToParent = std::function; using FinalizerFunc = std::function; using StaticIndexFunc = std::function; using StaticFunc = std::function; LuaClass(const String& name); - template - void Inherit(LuaClass

& parent); + template void Inherit(LuaClass

& parent); + template void Inherit(LuaClass

& parent, ConvertToParent

convertFunc); void Register(LuaInstance& lua); @@ -57,7 +58,7 @@ namespace Nz void SetStaticSetter(StaticIndexFunc getter); private: - using ParentFunc = std::function; + using ParentFunc = std::function; using InstanceGetter = std::function; struct ClassInfo @@ -79,7 +80,7 @@ namespace Nz static int ConstructorProxy(lua_State* state); static int FinalizerProxy(lua_State* state); static int InfoDestructor(lua_State* state); - static void Get(const std::shared_ptr& info, LuaInstance& lua, T& instance); + static void Get(const std::shared_ptr& info, LuaInstance& lua, T* instance); static int GetterProxy(lua_State* state); static int MethodProxy(lua_State* state); static int SetterProxy(lua_State* state); diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 393225399..ffcc4b0d8 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -19,19 +19,29 @@ namespace Nz template template inline void LuaClass::Inherit(LuaClass

& parent) + { + Inherit

(parent, [] (T* instance) -> P* + { + return static_cast(instance); + }); + } + + template + template + inline void LuaClass::Inherit(LuaClass

& parent, ConvertToParent

convertFunc) { static_assert(!std::is_same::value || std::is_base_of::value, "P must be a base of T"); std::shared_ptr::ClassInfo>& parentInfo = parent.m_info; - - parentInfo->instanceGetters[m_info->name] = [info = m_info](LuaInstance& lua) -> P* + + parentInfo->instanceGetters[m_info->name] = [info = m_info, convertFunc] (LuaInstance& lua) -> P* { - return *static_cast(lua.CheckUserdata(1, info->name)); + return convertFunc(*static_cast(lua.CheckUserdata(1, info->name))); }; - m_info->parentGetters.emplace_back([parentInfo] (LuaInstance& lua, T& instance) + m_info->parentGetters.emplace_back([parentInfo, convertFunc] (LuaInstance& lua, T* instance) { - LuaClass

::Get(parentInfo, lua, instance); + LuaClass

::Get(parentInfo, lua, convertFunc(instance)); }); } @@ -112,7 +122,7 @@ namespace Nz lua.SetField(pair.first); // Method name } - m_info->instanceGetters[m_info->name] = [info = m_info](LuaInstance& lua) + m_info->instanceGetters[m_info->name] = [info = m_info] (LuaInstance& lua) { return *static_cast(lua.CheckUserdata(1, info->name)); }; @@ -242,7 +252,7 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -256,7 +266,7 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -355,11 +365,11 @@ namespace Nz } template - void LuaClass::Get(const std::shared_ptr& info, LuaInstance& lua, T& instance) + void LuaClass::Get(const std::shared_ptr& info, LuaInstance& lua, T* instance) { const ClassIndexFunc& getter = info->getter; - if (!getter || !getter(lua, instance)) + if (!getter || !getter(lua, *instance)) { // Query from the metatable lua.GetMetatable(info->name); //< Metatable @@ -389,7 +399,7 @@ namespace Nz std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + T* instance = *static_cast(lua.CheckUserdata(1, info->name)); lua.Remove(1); //< Remove the instance from the Lua stack Get(info, lua, instance); @@ -415,9 +425,15 @@ namespace Nz instance = it->second(lua); } lua.Pop(2); + + lua.Remove(1); //< Remove the instance from the Lua stack } - lua.Remove(1); //< Remove the instance from the Lua stack + if (!instance) + { + lua.Error("Method cannot be called without an object"); + return 0; + } unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); const ClassFunc& method = info->methods[index]; From 2b51a8b4b63f0b81ab3dcb0b17e4c99bd5957b4c Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:36:54 +0200 Subject: [PATCH 182/229] Sdk/Console: Add command history Former-commit-id: e5b437988a3f81b2724c0f1a45da0bbfc85b14b0 --- SDK/include/NDK/Console.hpp | 4 +++ SDK/src/NDK/Console.cpp | 53 ++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 1f0d36930..0f6c08d43 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,7 @@ namespace Ndk inline bool IsVisible() const; void SendCharacter(char32_t character); + void SendEvent(Nz::WindowEvent event); void SetCharacterSize(unsigned int size); void SetSize(const Nz::Vector2f& size); @@ -65,6 +67,8 @@ namespace Ndk Nz::String text; }; + std::size_t m_historyPosition; + std::vector m_commandHistory; std::vector m_historyLines; EntityOwner m_historyBackground; EntityOwner m_history; diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index da16e3aa2..976bb7fd1 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -20,6 +20,7 @@ namespace Ndk } Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) : + m_historyPosition(0), m_defaultFont(Nz::Font::GetDefault()), m_instance(instance), m_size(size), @@ -81,10 +82,10 @@ namespace Ndk Ndk::NodeComponent& inputNode = m_input->AddComponent(); inputNode.SetParent(this); - + Layout(); } - + void Console::AddLine(const Nz::String& text, const Nz::Color& color) { AddLineInternal(text, color); @@ -124,6 +125,40 @@ namespace Ndk m_inputTextSprite->Update(m_inputDrawer); } + void Console::SendEvent(Nz::WindowEvent event) + { + switch (event.type) + { + case Nz::WindowEventType_TextEntered: + SendCharacter(event.text.character); + break; + + case Nz::WindowEventType_KeyPressed: + { + switch (event.key.code) + { + case Nz::Keyboard::Down: + case Nz::Keyboard::Up: + if (event.key.code == Nz::Keyboard::Up) + m_historyPosition = std::min(m_commandHistory.size(), m_historyPosition + 1); + else + { + if (m_historyPosition > 1) + m_historyPosition--; + else if (m_historyPosition == 0) + m_historyPosition = 1; + } + + Nz::String text = m_commandHistory[m_commandHistory.size() - m_historyPosition]; + m_inputDrawer.SetText(s_inputPrefix + text); + m_inputTextSprite->Update(m_inputDrawer); + break; + } + break; + } + } + } + void Console::SetCharacterSize(unsigned int size) { m_characterSize = size; @@ -162,12 +197,18 @@ namespace Ndk void Console::ExecuteInput() { - Nz::String input = m_inputDrawer.GetText().SubString(s_inputPrefixSize); + Nz::String input = m_inputDrawer.GetText(); + Nz::String inputCmd = input.SubString(s_inputPrefixSize);; m_inputDrawer.SetText(s_inputPrefix); - AddLineInternal(input); + if (m_commandHistory.empty() || m_commandHistory.back() != inputCmd) + m_commandHistory.push_back(inputCmd); - if (!m_instance.Execute(input)) + m_historyPosition = 0; + + AddLineInternal(input); //< With the input prefix + + if (!m_instance.Execute(inputCmd)) AddLineInternal(m_instance.GetLastError(), Nz::Color::Red); RefreshHistory(); @@ -210,7 +251,7 @@ namespace Ndk m_historyDrawer.AppendText(it->text); ++it; } - + m_historyDrawer.AppendText(Nz::String('\n')); } From 115565fa1eb043782a67572a23831c0334bbfc11 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:37:31 +0200 Subject: [PATCH 183/229] Network/Enums: Fix SocketState_Max Former-commit-id: 93f0502110b74a56101dc7216adeef18afe48d70 --- include/Nazara/Network/Enums.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 81c5f7c3d..32d9484ae 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -97,7 +97,7 @@ namespace Nz SocketState_NotConnected, //< The socket is not connected (or has been disconnected) SocketState_Resolving, //< The socket is currently resolving a host name - SocketState_Max = SocketState_NotConnected + SocketState_Max = SocketState_Resolving }; enum SocketType From 3adae93ea9fd952969e243aed0842cb902801757 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Mar 2016 18:37:41 +0200 Subject: [PATCH 184/229] Fix whitespace Former-commit-id: 17b52d16923deeda808c093ed499d88217ecf5d7 --- include/Nazara/Network/Network.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Network/Network.hpp b/include/Nazara/Network/Network.hpp index 93b0e921f..16cf940d2 100644 --- a/include/Nazara/Network/Network.hpp +++ b/include/Nazara/Network/Network.hpp @@ -27,7 +27,7 @@ namespace Nz private: static unsigned int s_moduleReferenceCounter; - }; + }; } #endif // NAZARA_MODULENAME_HPP From a2f6e54104917c51c2f33a50e5397bd5a9994185 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 20:15:38 +0200 Subject: [PATCH 185/229] Sdk/BaseComponent: Add GetMaxComponentIndex static method Former-commit-id: b3413066bcb5b9f7b7b84092a2645154ad6d8005 --- SDK/include/NDK/BaseComponent.hpp | 2 ++ SDK/include/NDK/BaseComponent.inl | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index be738b737..5ec1d53b6 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -31,6 +31,8 @@ namespace Ndk ComponentIndex GetIndex() const; + inline static ComponentIndex GetMaxComponentIndex(); + BaseComponent& operator=(const BaseComponent&) = default; BaseComponent& operator=(BaseComponent&&) = default; diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index b8637b457..f6bd79578 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include namespace Ndk @@ -17,6 +18,11 @@ namespace Ndk return m_componentIndex; } + inline ComponentIndex BaseComponent::GetMaxComponentIndex() + { + return static_cast(s_entries.size()); + } + inline ComponentIndex BaseComponent::RegisterComponent(ComponentId id, Factory factoryFunc) { // Nous allons rajouter notre composant à la fin From a77ad42fcb403369c2af23df0a168763d25725cb Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 21:14:22 +0200 Subject: [PATCH 186/229] Add generic handlers Former-commit-id: 8fc343d3a056de8031cf453748b8801d50d3710e --- SDK/include/NDK/BaseComponent.hpp | 2 +- SDK/include/NDK/BaseSystem.hpp | 2 +- SDK/include/NDK/Entity.hpp | 15 +- SDK/include/NDK/Entity.inl | 33 +-- SDK/include/NDK/EntityHandle.hpp | 89 -------- SDK/include/NDK/EntityHandle.inl | 280 -------------------------- SDK/include/NDK/EntityList.hpp | 2 +- SDK/include/NDK/EntityOwner.hpp | 2 +- SDK/include/NDK/EntityOwner.inl | 8 +- SDK/src/NDK/Entity.cpp | 16 +- SDK/src/NDK/EntityHandle.cpp | 10 - SDK/src/NDK/World.cpp | 2 +- include/Nazara/Core/HandledObject.hpp | 47 +++++ include/Nazara/Core/HandledObject.inl | 84 ++++++++ include/Nazara/Core/ObjectHandle.hpp | 93 +++++++++ include/Nazara/Core/ObjectHandle.inl | 280 ++++++++++++++++++++++++++ 16 files changed, 542 insertions(+), 423 deletions(-) delete mode 100644 SDK/include/NDK/EntityHandle.hpp delete mode 100644 SDK/include/NDK/EntityHandle.inl delete mode 100644 SDK/src/NDK/EntityHandle.cpp create mode 100644 include/Nazara/Core/HandledObject.hpp create mode 100644 include/Nazara/Core/HandledObject.inl create mode 100644 include/Nazara/Core/ObjectHandle.hpp create mode 100644 include/Nazara/Core/ObjectHandle.inl diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index 5ec1d53b6..f045ae2a6 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -7,7 +7,7 @@ #ifndef NDK_BASECOMPONENT_HPP #define NDK_BASECOMPONENT_HPP -#include +#include #include #include #include diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 9a81c83e0..8e828149d 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -8,7 +8,7 @@ #define NDK_BASESYSTEM_HPP #include -#include +#include #include namespace Ndk diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 71f5a4fc7..6069a13c0 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -8,6 +8,7 @@ #define NDK_ENTITY_HPP #include +#include #include #include #include @@ -15,13 +16,14 @@ namespace Ndk { class BaseComponent; - class EntityHandle; + class Entity; class World; - class NDK_API Entity + using EntityHandle = Nz::ObjectHandle; + + class NDK_API Entity : public Nz::HandledObject { friend class BaseSystem; - friend EntityHandle; friend World; public: @@ -32,8 +34,6 @@ namespace Ndk BaseComponent& AddComponent(std::unique_ptr&& component); template ComponentType& AddComponent(Args&&... args); - EntityHandle CreateHandle(); - inline void Enable(bool enable); inline BaseComponent& GetComponent(ComponentIndex index); @@ -56,6 +56,8 @@ namespace Ndk void RemoveComponent(ComponentIndex index); template void RemoveComponent(); + inline Nz::String ToString() const; + Entity& operator=(const Entity&) = delete; Entity& operator=(Entity&&) = delete; @@ -65,16 +67,13 @@ namespace Ndk void Create(); void Destroy(); - inline void RegisterHandle(EntityHandle* handle); inline void RegisterSystem(SystemIndex index); inline void SetWorld(World* world) noexcept; - inline void UnregisterHandle(EntityHandle* handle); inline void UnregisterSystem(SystemIndex index); std::vector> m_components; - std::vector m_handles; Nz::Bitset<> m_componentBits; Nz::Bitset<> m_systemBits; EntityId m_id; diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index caca8b766..799ffd97e 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include #include #include #include @@ -102,10 +103,10 @@ namespace Ndk RemoveComponent(index); } - inline void Entity::RegisterHandle(EntityHandle* handle) + inline Nz::String Entity::ToString() const { - ///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); + Nz::StringStream ss; + return ss << "Entity(" << GetId() << ')'; } inline void Entity::RegisterSystem(SystemIndex index) @@ -120,18 +121,24 @@ namespace Ndk m_world = world; } - inline void Entity::UnregisterHandle(EntityHandle* handle) - { - ///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); - - // On échange cet élément avec le dernier, et on diminue la taille du vector de 1 - std::swap(*it, m_handles.back()); - m_handles.pop_back(); - } - inline void Entity::UnregisterSystem(SystemIndex index) { m_systemBits.UnboundedReset(index); } } + +namespace std +{ + template<> + struct hash + { + size_t operator()(const Ndk::EntityHandle& handle) const + { + // Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée + // pour cette raison, nous devons hasher l'ID de l'entité (qui reste constante) + Ndk::EntityId id = (handle.IsValid()) ? handle->GetId() : std::numeric_limits::max(); + + return hash()(id); + } + }; +} \ No newline at end of file diff --git a/SDK/include/NDK/EntityHandle.hpp b/SDK/include/NDK/EntityHandle.hpp deleted file mode 100644 index 8a5594dbe..000000000 --- a/SDK/include/NDK/EntityHandle.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// 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_ENTITYHANDLE_HPP -#define NDK_ENTITYHANDLE_HPP - -#include -#include - -namespace Ndk -{ - class EntityHandle - { - friend Entity; - - public: - EntityHandle(); - explicit EntityHandle(Entity* entity); - EntityHandle(const EntityHandle& handle); - EntityHandle(EntityHandle&& handle); - ~EntityHandle(); - - Entity* GetEntity() const; - - bool IsValid() const; - - void Reset(Entity* entity = nullptr); - void Reset(const EntityHandle& handle); - void Reset(EntityHandle&& handle); - - EntityHandle& Swap(EntityHandle& handle); - - Nz::String ToString() const; - - operator bool() const; - operator Entity*() const; - Entity* operator->() const; - - EntityHandle& operator=(Entity* entity); - EntityHandle& operator=(const EntityHandle& handle); - EntityHandle& operator=(EntityHandle&& handle); - - friend std::ostream& operator<<(std::ostream& out, const EntityHandle& handle); - - friend bool operator==(const EntityHandle& lhs, const EntityHandle& rhs); - friend bool operator==(const Entity& lhs, const EntityHandle& rhs); - friend bool operator==(const EntityHandle& lhs, const Entity& rhs); - - friend bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs); - friend bool operator!=(const Entity& lhs, const EntityHandle& rhs); - friend bool operator!=(const EntityHandle& lhs, const Entity& rhs); - - friend bool operator<(const EntityHandle& lhs, const EntityHandle& rhs); - friend bool operator<(const Entity& lhs, const EntityHandle& rhs); - friend bool operator<(const EntityHandle& lhs, const Entity& rhs); - - friend bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs); - friend bool operator<=(const Entity& lhs, const EntityHandle& rhs); - friend bool operator<=(const EntityHandle& lhs, const Entity& rhs); - - friend bool operator>(const EntityHandle& lhs, const EntityHandle& rhs); - friend bool operator>(const Entity& lhs, const EntityHandle& rhs); - friend bool operator>(const EntityHandle& lhs, const Entity& rhs); - - friend bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs); - friend bool operator>=(const Entity& lhs, const EntityHandle& rhs); - friend bool operator>=(const EntityHandle& lhs, const Entity& rhs); - - static const EntityHandle InvalidHandle; - - protected: - void OnEntityDestroyed(); - void OnEntityMoved(Entity* newEntity); - - Entity* m_entity; - }; -} - -namespace std -{ - void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs); -} - -#include - -#endif // NDK_ENTITYHANDLE_HPP diff --git a/SDK/include/NDK/EntityHandle.inl b/SDK/include/NDK/EntityHandle.inl deleted file mode 100644 index 03e7ad829..000000000 --- a/SDK/include/NDK/EntityHandle.inl +++ /dev/null @@ -1,280 +0,0 @@ -// 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 -#include -#include - -namespace Ndk -{ - inline EntityHandle::EntityHandle() : - m_entity(nullptr) - { - } - - inline EntityHandle::EntityHandle(Entity* entity) : - EntityHandle() - { - Reset(entity); - } - - inline EntityHandle::EntityHandle(const EntityHandle& handle) : - EntityHandle() - { - Reset(handle); - } - - inline EntityHandle::EntityHandle(EntityHandle&& handle) : - EntityHandle() - { - Reset(handle); - } - - inline EntityHandle::~EntityHandle() - { - Reset(nullptr); - } - - inline Entity* EntityHandle::GetEntity() const - { - return m_entity; - } - - inline bool EntityHandle::IsValid() const - { - return m_entity != nullptr; - } - - inline void EntityHandle::Reset(Entity* entity) - { - // Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle - if (m_entity) - m_entity->UnregisterHandle(this); - - m_entity = entity; - if (m_entity) - // On informe la nouvelle entité que nous pointons sur elle - m_entity->RegisterHandle(this); - } - - inline void EntityHandle::Reset(const EntityHandle& handle) - { - Reset(handle.GetEntity()); - } - - inline void EntityHandle::Reset(EntityHandle&& handle) - { - Reset(handle.GetEntity()); - } - - inline EntityHandle& EntityHandle::Swap(EntityHandle& handle) - { - // Comme nous inversons les handles, nous devons prévenir les entités - // La version par défaut de swap (à base de move) aurait fonctionné, - // mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire). - if (m_entity) - { - m_entity->UnregisterHandle(this); - m_entity->RegisterHandle(&handle); - } - - if (handle.m_entity) - { - handle.m_entity->UnregisterHandle(&handle); - handle.m_entity->RegisterHandle(this); - } - - // On effectue l'échange - std::swap(m_entity, handle.m_entity); - return *this; - } - - inline Nz::String EntityHandle::ToString() const - { - Nz::StringStream ss; - ss << "EntityHandle("; - if (IsValid()) - ss << "Entity(" << m_entity->GetId() << ')'; - else - ss << "Null entity"; - - ss << ')'; - - return ss; - } - - inline EntityHandle::operator bool() const - { - return IsValid(); - } - - inline EntityHandle::operator Entity*() const - { - return m_entity; - } - - inline Entity* EntityHandle::operator->() const - { - return m_entity; - } - - inline EntityHandle& EntityHandle::operator=(Entity* entity) - { - Reset(entity); - - return *this; - } - - inline EntityHandle& EntityHandle::operator=(const EntityHandle& handle) - { - Reset(handle); - - return *this; - } - - inline EntityHandle& EntityHandle::operator=(EntityHandle&& handle) - { - Reset(std::move(handle)); - - return *this; - } - - inline void EntityHandle::OnEntityDestroyed() - { - // Un raccourci, un appel à Reset nous enlèverait de la liste des handles que nous ne pouvons pas modifier - // maintenant car elle est actuellement parcourue - m_entity = nullptr; - } - - inline void EntityHandle::OnEntityMoved(Entity* newEntity) - { - // L'entité a été déplacée (peut arriver lors d'un changement de taille du conteneur du monde) - // nous mettons à jour notre pointeur - m_entity = newEntity; - } - - inline std::ostream& operator<<(std::ostream& out, const EntityHandle& handle) - { - out << "EntityHandle("; - if (handle.IsValid()) - out << "Entity(" << handle->GetId() << ')'; - else - out << "Null entity"; - - out << ')'; - - return out; - } - - inline bool operator==(const EntityHandle& lhs, const EntityHandle& rhs) - { - return lhs.m_entity == rhs.m_entity; - } - - inline bool operator==(const Entity& lhs, const EntityHandle& rhs) - { - return &lhs == rhs.m_entity; - } - - inline bool operator==(const EntityHandle& lhs, const Entity& rhs) - { - return lhs.m_entity == &rhs; - } - - inline bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs) - { - return !(lhs == rhs); - } - - inline bool operator!=(const Entity& lhs, const EntityHandle& rhs) - { - return !(lhs == rhs); - } - - inline bool operator!=(const EntityHandle& lhs, const Entity& rhs) - { - return !(lhs == rhs); - } - - inline bool operator<(const EntityHandle& lhs, const EntityHandle& rhs) - { - return lhs.m_entity < rhs.m_entity; - } - - inline bool operator<(const Entity& lhs, const EntityHandle& rhs) - { - return &lhs < rhs.m_entity; - } - - inline bool operator<(const EntityHandle& lhs, const Entity& rhs) - { - return lhs.m_entity < &rhs; - } - - inline bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs) - { - return !(lhs > rhs); - } - - inline bool operator<=(const Entity& lhs, const EntityHandle& rhs) - { - return !(lhs > rhs); - } - - inline bool operator<=(const EntityHandle& lhs, const Entity& rhs) - { - return !(lhs > rhs); - } - - inline bool operator>(const EntityHandle& lhs, const EntityHandle& rhs) - { - return rhs < lhs; - } - - inline bool operator>(const Entity& lhs, const EntityHandle& rhs) - { - return rhs < lhs; - } - - inline bool operator>(const EntityHandle& lhs, const Entity& rhs) - { - return rhs < lhs; - } - - inline bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs) - { - return !(lhs < rhs); - } - - inline bool operator>=(const Entity& lhs, const EntityHandle& rhs) - { - return !(lhs < rhs); - } - - inline bool operator>=(const EntityHandle& lhs, const Entity& rhs) - { - return !(lhs < rhs); - } -} - -namespace std -{ - template<> - struct hash - { - size_t operator()(const Ndk::EntityHandle& handle) const - { - // Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée - // pour cette raison, nous devons hasher l'ID de l'entité (qui reste constante) - Ndk::EntityId id = (handle.IsValid()) ? handle->GetId() : std::numeric_limits::max(); - - return hash()(id); - } - }; - - inline void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs) - { - lhs.Swap(rhs); - } -} diff --git a/SDK/include/NDK/EntityList.hpp b/SDK/include/NDK/EntityList.hpp index 0edefde11..006967413 100644 --- a/SDK/include/NDK/EntityList.hpp +++ b/SDK/include/NDK/EntityList.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Ndk { diff --git a/SDK/include/NDK/EntityOwner.hpp b/SDK/include/NDK/EntityOwner.hpp index 94dcf0566..c7cab901f 100644 --- a/SDK/include/NDK/EntityOwner.hpp +++ b/SDK/include/NDK/EntityOwner.hpp @@ -7,7 +7,7 @@ #ifndef NDK_ENTITYOWNER_HPP #define NDK_ENTITYOWNER_HPP -#include +#include namespace Ndk { diff --git a/SDK/include/NDK/EntityOwner.inl b/SDK/include/NDK/EntityOwner.inl index e32094eaa..607f3229d 100644 --- a/SDK/include/NDK/EntityOwner.inl +++ b/SDK/include/NDK/EntityOwner.inl @@ -26,16 +26,16 @@ namespace Ndk inline void EntityOwner::Reset(Entity* entity) { - if (m_entity) - m_entity->Kill(); + if (m_object) + m_object->Kill(); EntityHandle::Reset(entity); } inline void EntityOwner::Reset(EntityOwner&& handle) { - Reset(handle.GetEntity()); - handle.m_entity = nullptr; + Reset(handle.GetObject()); + handle.m_object = nullptr; } inline EntityOwner& EntityOwner::operator=(Entity* entity) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index afd3aa1b6..17730a234 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -4,14 +4,13 @@ #include #include -#include #include namespace Ndk { Entity::Entity(Entity&& entity) : + HandledObject(std::move(entity)), m_components(std::move(entity.m_components)), - m_handles(std::move(entity.m_handles)), m_componentBits(std::move(entity.m_componentBits)), m_systemBits(std::move(entity.m_systemBits)), m_id(entity.m_id), @@ -19,8 +18,6 @@ namespace Ndk m_enabled(entity.m_enabled), m_valid(entity.m_valid) { - for (EntityHandle* handle : m_handles) - handle->OnEntityMoved(this); } Entity::Entity(World* world, EntityId id) : @@ -63,11 +60,6 @@ namespace Ndk return component; } - EntityHandle Entity::CreateHandle() - { - return EntityHandle(this); - } - void Entity::Kill() { m_world->KillEntity(this); @@ -132,11 +124,7 @@ namespace Ndk } m_systemBits.Clear(); - // On informe chaque handle de notre destruction pour éviter qu'il ne continue de pointer sur nous - for (EntityHandle* handle : m_handles) - handle->OnEntityDestroyed(); - - m_handles.clear(); + UnregisterAllHandles(); m_valid = false; } diff --git a/SDK/src/NDK/EntityHandle.cpp b/SDK/src/NDK/EntityHandle.cpp deleted file mode 100644 index 7b9d035e3..000000000 --- a/SDK/src/NDK/EntityHandle.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// 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 - -namespace Ndk -{ - const EntityHandle EntityHandle::InvalidHandle; -} diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 483af6d27..1762f1d12 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -61,7 +61,7 @@ namespace Ndk void World::Clear() noexcept { - ///DOC: Tous les handles sont correctement invalidés + ///DOC: Tous les handles sont correctement invalidés, les entités sont immédiatement invalidées // Destruction des entités d'abord, et des handles ensuite // ceci pour éviter que les handles n'informent les entités inutilement lors de leur destruction diff --git a/include/Nazara/Core/HandledObject.hpp b/include/Nazara/Core/HandledObject.hpp new file mode 100644 index 000000000..f1e096748 --- /dev/null +++ b/include/Nazara/Core/HandledObject.hpp @@ -0,0 +1,47 @@ +// 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 NAZARA_OBJECTHANDLER_HPP +#define NAZARA_OBJECTHANDLER_HPP + +#include +#include +#include + +namespace Nz +{ + template class ObjectHandle; + + template + class HandledObject + { + friend ObjectHandle; + + public: + HandledObject() = default; + HandledObject(const HandledObject& object); + HandledObject(HandledObject&& object); + ~HandledObject(); + + ObjectHandle CreateHandle(); + + HandledObject& operator=(const HandledObject& object); + HandledObject& operator=(HandledObject&& object); + + protected: + void UnregisterAllHandles(); + + private: + void RegisterHandle(ObjectHandle* handle); + void UnregisterHandle(ObjectHandle* handle); + + std::vector*> m_handles; + }; +} + +#include + +#endif // NAZARA_OBJECTHANDLER_HPP diff --git a/include/Nazara/Core/HandledObject.inl b/include/Nazara/Core/HandledObject.inl new file mode 100644 index 000000000..53a5065f4 --- /dev/null +++ b/include/Nazara/Core/HandledObject.inl @@ -0,0 +1,84 @@ +// 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 +#include +#include +#include +#include + +namespace Nz +{ + template + HandledObject::HandledObject(const HandledObject& object) + { + // Don't copy anything, we're a copy of the object, we have no handle right now + } + + template + HandledObject::HandledObject(HandledObject&& object) : + m_handles(std::move(object.m_handles)) + { + for (ObjectHandle* handle : m_handles) + handle->OnObjectMoved(static_cast(this)); + } + + template + HandledObject::~HandledObject() + { + UnregisterAllHandles(); + } + + template + ObjectHandle HandledObject::CreateHandle() + { + return ObjectHandle(static_cast(this)); + } + + template + HandledObject& HandledObject::operator=(const HandledObject& object) + { + // Nothing to do + return *this; + } + + template + HandledObject& HandledObject::operator=(HandledObject&& object) + { + m_handles = std::move(object.m_handles); + for (ObjectHandle* handle : m_handles) + handle->OnObjectMoved(static_cast(this)); + + return *this; + } + + template + void HandledObject::RegisterHandle(ObjectHandle* 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); + } + + template + void HandledObject::UnregisterAllHandles() + { + // Tell every handle we got destroyed, to null them + for (ObjectHandle* handle : m_handles) + handle->OnObjectDestroyed(); + + m_handles.clear(); + } + + template + void HandledObject::UnregisterHandle(ObjectHandle* handle) + { + ///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); + NazaraAssert(it != m_handles.end(), "Handle not registred"); + + // On échange cet élément avec le dernier, et on diminue la taille du vector de 1 + std::swap(*it, m_handles.back()); + m_handles.pop_back(); + } +} diff --git a/include/Nazara/Core/ObjectHandle.hpp b/include/Nazara/Core/ObjectHandle.hpp new file mode 100644 index 000000000..d7a53e281 --- /dev/null +++ b/include/Nazara/Core/ObjectHandle.hpp @@ -0,0 +1,93 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_OBJECTHANDLE_HPP +#define NAZARA_OBJECTHANDLE_HPP + +#include +#include + +namespace Nz +{ + template class HandledObject; + + template + class ObjectHandle + { + friend HandledObject; + + public: + ObjectHandle(); + explicit ObjectHandle(T* object); + ObjectHandle(const ObjectHandle& handle); + ~ObjectHandle(); + + T* GetObject() const; + + bool IsValid() const; + + void Reset(T* object = nullptr); + void Reset(const ObjectHandle& handle); + + ObjectHandle& Swap(ObjectHandle& handle); + + Nz::String ToString() const; + + operator bool() const; + operator T*() const; + T* operator->() const; + + ObjectHandle& operator=(T* object); + ObjectHandle& operator=(const ObjectHandle& handle); + + static const ObjectHandle InvalidHandle; + + protected: + void OnObjectDestroyed(); + void OnObjectMoved(T* newObject); + + T* m_object; + }; + + template std::ostream& operator<<(std::ostream& out, const ObjectHandle& handle); + + template bool operator==(const ObjectHandle& lhs, const ObjectHandle& rhs); + template bool operator==(const T& lhs, const ObjectHandle& rhs); + template bool operator==(const ObjectHandle& lhs, const T& rhs); + + template bool operator!=(const ObjectHandle& lhs, const ObjectHandle& rhs); + template bool operator!=(const T& lhs, const ObjectHandle& rhs); + template bool operator!=(const ObjectHandle& lhs, const T& rhs); + + template bool operator<(const ObjectHandle& lhs, const ObjectHandle& rhs); + template bool operator<(const T& lhs, const ObjectHandle& rhs); + template bool operator<(const ObjectHandle& lhs, const T& rhs); + + template bool operator<=(const ObjectHandle, const ObjectHandle& rhs); + template bool operator<=(const T& lhs, const ObjectHandle& rhs); + template bool operator<=(const ObjectHandle& lhs, const T& rhs); + + template bool operator>(const ObjectHandle& lhs, const ObjectHandle& rhs); + template bool operator>(const T& lhs, const ObjectHandle& rhs); + template bool operator>(const ObjectHandle& lhs, const T& rhs); + + template bool operator>=(const ObjectHandle& lhs, const ObjectHandle& rhs); + template bool operator>=(const T& lhs, const ObjectHandle& rhs); + template bool operator>=(const ObjectHandle& lhs, const T& rhs); + + template struct PointedType> { typedef T type; }; + template struct PointedType> { typedef T type; }; +} + +namespace std +{ + template + void swap(Nz::ObjectHandle& lhs, Nz::ObjectHandle& rhs); +} + +#include + +#endif // NAZARA_OBJECTHANDLE_HPP diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl new file mode 100644 index 000000000..752cb96c0 --- /dev/null +++ b/include/Nazara/Core/ObjectHandle.inl @@ -0,0 +1,280 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + template + ObjectHandle::ObjectHandle() : + m_object(nullptr) + { + } + + template + ObjectHandle::ObjectHandle(T* object) : + ObjectHandle() + { + Reset(object); + } + + template + ObjectHandle::ObjectHandle(const ObjectHandle& handle) : + ObjectHandle() + { + Reset(handle); + } + + template + ObjectHandle::~ObjectHandle() + { + Reset(nullptr); + } + + template + T* ObjectHandle::GetObject() const + { + return m_object; + } + + template + bool ObjectHandle::IsValid() const + { + return m_object != nullptr; + } + + template + void ObjectHandle::Reset(T* object) + { + // Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle + if (m_object) + m_object->UnregisterHandle(this); + + m_object = object; + if (m_object) + // On informe la nouvelle entité que nous pointons sur elle + m_object->RegisterHandle(this); + } + + template + void ObjectHandle::Reset(const ObjectHandle& handle) + { + Reset(handle.GetObject()); + } + + template + ObjectHandle& ObjectHandle::Swap(ObjectHandle& handle) + { + // Comme nous inversons les handles, nous devons prévenir les entités + // La version par défaut de swap (à base de move) aurait fonctionné, + // mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire). + if (m_object) + { + m_object->UnregisterHandle(this); + m_object->RegisterHandle(&handle); + } + + if (handle.m_object) + { + handle.m_object->UnregisterHandle(&handle); + handle.m_object->RegisterHandle(this); + } + + // On effectue l'échange + std::swap(m_object, handle.m_object); + return *this; + } + + template + Nz::String ObjectHandle::ToString() const + { + Nz::StringStream ss; + ss << "ObjectHandle("; + if (IsValid()) + ss << m_object->ToString(); + else + ss << "Null"; + + ss << ')'; + + return ss; + } + + template + ObjectHandle::operator bool() const + { + return IsValid(); + } + + template + ObjectHandle::operator T*() const + { + return m_object; + } + + template + T* ObjectHandle::operator->() const + { + return m_object; + } + + template + ObjectHandle& ObjectHandle::operator=(T* entity) + { + Reset(entity); + + return *this; + } + + template + ObjectHandle& ObjectHandle::operator=(const ObjectHandle& handle) + { + Reset(handle); + + return *this; + } + + template + void ObjectHandle::OnObjectDestroyed() + { + // Shortcut + m_object = nullptr; + } + + template + void ObjectHandle::OnObjectMoved(T* newObject) + { + // The object has been moved, update our pointer + m_object = newObject; + } + + template + std::ostream& operator<<(std::ostream& out, const ObjectHandle& handle) + { + return handle.ToString(); + } + + template + bool operator==(const ObjectHandle& lhs, const ObjectHandle& rhs) + { + return lhs.GetObject() == rhs.GetObject(); + } + + template + bool operator==(const T& lhs, const ObjectHandle& rhs) + { + return &lhs == rhs.GetObject(); + } + + template + bool operator==(const ObjectHandle& lhs, const T& rhs) + { + return lhs.GetObject() == &rhs; + } + + template + bool operator!=(const ObjectHandle& lhs, const ObjectHandle& rhs) + { + return !(lhs == rhs); + } + + template + bool operator!=(const T& lhs, const ObjectHandle& rhs) + { + return !(lhs == rhs); + } + + template + bool operator!=(const ObjectHandle& lhs, const T& rhs) + { + return !(lhs == rhs); + } + + template + bool operator<(const ObjectHandle& lhs, const ObjectHandle& rhs) + { + return lhs.m_object < rhs.m_object; + } + + template + bool operator<(const T& lhs, const ObjectHandle& rhs) + { + return &lhs < rhs.m_object; + } + + template + bool operator<(const ObjectHandle& lhs, const T& rhs) + { + return lhs.m_object < &rhs; + } + + template + bool operator<=(const ObjectHandle& lhs, const ObjectHandle& rhs) + { + return !(lhs > rhs); + } + + template + bool operator<=(const T& lhs, const ObjectHandle& rhs) + { + return !(lhs > rhs); + } + + template + bool operator<=(const ObjectHandle& lhs, const T& rhs) + { + return !(lhs > rhs); + } + + template + bool operator>(const ObjectHandle& lhs, const ObjectHandle& rhs) + { + return rhs < lhs; + } + + template + bool operator>(const T& lhs, const ObjectHandle& rhs) + { + return rhs < lhs; + } + + template + bool operator>(const ObjectHandle& lhs, const T& rhs) + { + return rhs < lhs; + } + + template + bool operator>=(const ObjectHandle& lhs, const ObjectHandle& rhs) + { + return !(lhs < rhs); + } + + template + bool operator>=(const T& lhs, const ObjectHandle& rhs) + { + return !(lhs < rhs); + } + + template + bool operator>=(const ObjectHandle& lhs, const T& rhs) + { + return !(lhs < rhs); + } + + template + const ObjectHandle ObjectHandle::InvalidHandle; +} + +namespace std +{ + template + void swap(Nz::ObjectHandle& lhs, Nz::ObjectHandle& rhs) + { + lhs.Swap(rhs); + } +} From 64cd5e0cf3dcfce8b93b824ec4a9acabcd34a1a0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 21:14:55 +0200 Subject: [PATCH 187/229] Sdk: Add WorldHandle Former-commit-id: 70141670052728f93093922471835d0aa30acce3 --- SDK/include/NDK/World.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index ff1de0ef7..40508e8e4 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -8,8 +8,8 @@ #define NDK_WORLD_HPP #include +#include #include -#include #include #include #include @@ -18,7 +18,11 @@ namespace Ndk { - class NDK_API World + class World; + + using WorldHandle = Nz::ObjectHandle; + + class NDK_API World : public Nz::HandledObject { friend Entity; From 1c1625070ebd747bd5e939c50bf4b358e89aa3d2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 21:15:10 +0200 Subject: [PATCH 188/229] Sdk: Add GraphicsComponentHandle Former-commit-id: 437240bf060a20c92f29c03a8f913fc7355dab05 --- SDK/include/NDK/Components/GraphicsComponent.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 4a32f90e5..f8fa2bf66 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -13,7 +13,11 @@ namespace Ndk { - class NDK_API GraphicsComponent : public Component + class GraphicsComponent; + + using GraphicsComponentHandle = Nz::ObjectHandle; + + class NDK_API GraphicsComponent : public Component, public Nz::HandledObject { friend class RenderSystem; From 82d1fbb057e49232b4523b7a70a58664a4f43d04 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 21:15:17 +0200 Subject: [PATCH 189/229] Sdk: Add NodeComponentHandle Former-commit-id: 74e925d0eb39e99e57429c5c769ff827cc04e9c8 --- SDK/include/NDK/Components/NodeComponent.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/Components/NodeComponent.hpp b/SDK/include/NDK/Components/NodeComponent.hpp index 1e6eee879..c2a4eeb83 100644 --- a/SDK/include/NDK/Components/NodeComponent.hpp +++ b/SDK/include/NDK/Components/NodeComponent.hpp @@ -13,8 +13,11 @@ namespace Ndk { class Entity; + class NodeComponent; - class NDK_API NodeComponent : public Component, public Nz::Node + using NodeComponentHandle = Nz::ObjectHandle; + + class NDK_API NodeComponent : public Component, public Nz::Node, public Nz::HandledObject { public: NodeComponent() = default; From 809c340edc892f9af10097d0b0254a2c82f51d4a Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 21:16:05 +0200 Subject: [PATCH 190/229] Sdk: Add Network binding Former-commit-id: 8cc96ed5e00f680d347ac7f51dfb5a80b3252b0e --- SDK/include/NDK/LuaAPI.hpp | 1 + SDK/include/NDK/LuaAPI.inl | 6 + SDK/src/NDK/LuaAPI_Network.cpp | 215 +++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 SDK/src/NDK/LuaAPI_Network.cpp diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index fe8e343ce..3a420707b 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -26,6 +26,7 @@ namespace Ndk static void Register_Core(Nz::LuaInstance& instance); static void Register_Graphics(Nz::LuaInstance& instance); static void Register_Math(Nz::LuaInstance& instance); + static void Register_Network(Nz::LuaInstance& instance); static void Register_Renderer(Nz::LuaInstance& instance); static void Register_Utility(Nz::LuaInstance& instance); }; diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 79c1feb86..4599d3f16 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -64,6 +64,12 @@ namespace Nz return 1; } + inline int LuaImplReplyVal(const LuaInstance& instance, IpAddress val, TypeTag) + { + instance.PushInstance("IpAddress", val); + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d val, TypeTag) { instance.PushInstance("Vector3", val); diff --git a/SDK/src/NDK/LuaAPI_Network.cpp b/SDK/src/NDK/LuaAPI_Network.cpp new file mode 100644 index 000000000..e5a36ac7d --- /dev/null +++ b/SDK/src/NDK/LuaAPI_Network.cpp @@ -0,0 +1,215 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include +#include + +namespace Ndk +{ + void LuaAPI::Register_Network(Nz::LuaInstance& instance) + { + /*********************************** Nz::AbstractSocket **********************************/ + Nz::LuaClass abstractSocketClass("AbstractSocket"); + + abstractSocketClass.SetMethod("Close", &Nz::AbstractSocket::Close); + abstractSocketClass.SetMethod("EnableBlocking", &Nz::AbstractSocket::EnableBlocking); + abstractSocketClass.SetMethod("GetLastError", &Nz::AbstractSocket::GetLastError); + abstractSocketClass.SetMethod("GetState", &Nz::AbstractSocket::GetState); + abstractSocketClass.SetMethod("GetType", &Nz::AbstractSocket::GetType); + abstractSocketClass.SetMethod("IsBlockingEnabled", &Nz::AbstractSocket::IsBlockingEnabled); + abstractSocketClass.SetMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes); + + abstractSocketClass.Register(instance); + + Nz::LuaClass ipAddressClass("IpAddress"); + + ipAddressClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::IpAddress* + { + unsigned int argCount = std::min(lua.GetStackTop(), 9U); + + int argIndex = 1; + switch (argCount) + { + case 0: + return new Nz::IpAddress; + + case 1: + return new Nz::IpAddress(lua.CheckString(argIndex)); + + case 4: + case 5: + return new Nz::IpAddress(lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex, 0)); + + case 8: + case 9: + return new Nz::IpAddress(lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), + lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex, 0)); + } + + return nullptr; + }); + + ipAddressClass.SetMethod("GetPort", &Nz::IpAddress::GetPort); + ipAddressClass.SetMethod("GetProtocol", &Nz::IpAddress::GetProtocol); + ipAddressClass.SetMethod("IsLoopback", &Nz::IpAddress::IsLoopback); + ipAddressClass.SetMethod("IsValid", &Nz::IpAddress::IsValid); + ipAddressClass.SetMethod("ToUInt32", &Nz::IpAddress::ToUInt32); + ipAddressClass.SetMethod("__tostring", &Nz::IpAddress::ToString); + + ipAddressClass.SetStaticMethod("ResolveAddress", [] (Nz::LuaInstance& instance) -> int + { + Nz::String service; + Nz::ResolveError error = Nz::ResolveError_Unknown; + + int argIndex = 1; + Nz::String hostName = Nz::IpAddress::ResolveAddress(instance.Check(&argIndex), &service, &error); + + if (error == Nz::ResolveError_NoError) + { + instance.Push(hostName); + instance.Push(service); + return 2; + } + else + { + instance.PushBoolean(false); + instance.Push(error); + return 2; + } + }); + + ipAddressClass.SetStaticMethod("ResolveHostname", [] (Nz::LuaInstance& instance) -> int + { + Nz::ResolveError error = Nz::ResolveError_Unknown; + + int argIndex = 1; + Nz::NetProtocol protocol = instance.Check(&argIndex); + Nz::String hostname = instance.Check(&argIndex); + Nz::String service = instance.Check(&argIndex, "http"); + + std::vector addresses = Nz::IpAddress::ResolveHostname(protocol, hostname, service, &error); + if (error == Nz::ResolveError_NoError) + { + int index = 1; + instance.PushTable(addresses.size()); + for (Nz::HostnameInfo& info : addresses) + { + instance.PushInteger(index++); + instance.PushTable(0, 4); + instance.SetField("Address", std::move(info.address)); + instance.SetField("CanonicalName", std::move(info.canonicalName)); + instance.SetField("Protocol", std::move(info.protocol)); + instance.SetField("SocketType", std::move(info.socketType)); + instance.SetTable(); + } + + return 1; + } + else + { + instance.PushBoolean(false); + instance.Push(error); + return 2; + } + }); + + ipAddressClass.Register(instance); + + // Enums + + // Nz::NetProtocol + static_assert(Nz::NetProtocol_Max + 1 == 4, "Nz::NetProtocol has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 4); + { + instance.SetField("Any", Nz::NetProtocol_Any); + instance.SetField("IPv4", Nz::NetProtocol_IPv4); + instance.SetField("IPv6", Nz::NetProtocol_IPv6); + instance.SetField("Unknown", Nz::NetProtocol_Unknown); + } + instance.SetGlobal("NetProtocol"); + + // Nz::PacketPriority + static_assert(Nz::PacketPriority_Max + 1 == 4, "Nz::PacketPriority has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 6); + { + instance.SetField("High", Nz::PacketPriority_High); + instance.SetField("Highest", Nz::PacketPriority_Highest); + instance.SetField("Immediate", Nz::PacketPriority_Immediate); + instance.SetField("Medium", Nz::PacketPriority_Medium); + instance.SetField("Low", Nz::PacketPriority_Low); + instance.SetField("Lowest", Nz::PacketPriority_Lowest); + } + instance.SetGlobal("PacketPriority"); + + // Nz::PacketReliability + static_assert(Nz::PacketReliability_Max + 1 == 3, "Nz::PacketReliability has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 3); + { + instance.SetField("Reliable", Nz::PacketReliability_Reliable); + instance.SetField("ReliableOrdered", Nz::PacketReliability_ReliableOrdered); + instance.SetField("Unreliable", Nz::PacketReliability_Unreliable); + } + instance.SetGlobal("PacketReliability"); + + // Nz::ResolveError + static_assert(Nz::ResolveError_Max + 1 == 9, "Nz::ResolveError has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 9); + { + instance.SetField("Internal", Nz::ResolveError_Internal); + instance.SetField("ResourceError", Nz::ResolveError_ResourceError); + instance.SetField("NoError", Nz::ResolveError_NoError); + instance.SetField("NonRecoverable", Nz::ResolveError_NonRecoverable); + instance.SetField("NotFound", Nz::ResolveError_NotFound); + instance.SetField("NotInitialized", Nz::ResolveError_NotInitialized); + instance.SetField("ProtocolNotSupported", Nz::ResolveError_ProtocolNotSupported); + instance.SetField("TemporaryFailure", Nz::ResolveError_TemporaryFailure); + instance.SetField("Unknown", Nz::ResolveError_Unknown); + } + instance.SetGlobal("ResolveError"); + + // Nz::SocketError + static_assert(Nz::SocketError_Max + 1 == 15, "Nz::ResolveError has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 15); + { + instance.SetField("AddressNotAvailable", Nz::SocketError_AddressNotAvailable); + instance.SetField("ConnectionClosed", Nz::SocketError_ConnectionClosed); + instance.SetField("ConnectionRefused", Nz::SocketError_ConnectionRefused); + instance.SetField("DatagramSize", Nz::SocketError_DatagramSize); + instance.SetField("Internal", Nz::SocketError_Internal); + instance.SetField("Packet", Nz::SocketError_Packet); + instance.SetField("NetworkError", Nz::SocketError_NetworkError); + instance.SetField("NoError", Nz::SocketError_NoError); + instance.SetField("NotInitialized", Nz::SocketError_NotInitialized); + instance.SetField("NotSupported", Nz::SocketError_NotSupported); + instance.SetField("ResolveError", Nz::SocketError_ResolveError); + instance.SetField("ResourceError", Nz::SocketError_ResourceError); + instance.SetField("TimedOut", Nz::SocketError_TimedOut); + instance.SetField("Unknown", Nz::SocketError_Unknown); + instance.SetField("UnreachableHost", Nz::SocketError_UnreachableHost); + } + instance.SetGlobal("SocketError"); + + // Nz::SocketState + static_assert(Nz::SocketState_Max + 1 == 5, "Nz::SocketState has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 5); + { + instance.SetField("Bound", Nz::SocketState_Bound); + instance.SetField("Connecting", Nz::SocketState_Connecting); + instance.SetField("Connected", Nz::SocketState_Connected); + instance.SetField("NotConnected", Nz::SocketState_NotConnected); + instance.SetField("Resolving", Nz::SocketState_Resolving); + } + instance.SetGlobal("SocketState"); + + // Nz::SocketType + static_assert(Nz::SocketType_Max + 1 == 4, "Nz::SocketState has been updated but change was not reflected to Lua binding"); + instance.PushTable(0, 4); + { + instance.SetField("Raw", Nz::SocketType_Raw); + instance.SetField("TCP", Nz::SocketType_TCP); + instance.SetField("UDP", Nz::SocketType_UDP); + instance.SetField("Unknown", Nz::SocketType_Unknown); + } + instance.SetGlobal("SocketType"); + } +} From 1ecc52c718c535fb1fcc56904bd5beab0d9d3417 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 21:16:48 +0200 Subject: [PATCH 191/229] Sdk: Add binding of SDK Former-commit-id: 4bad2b5db52a2fe459ad7802eb4a894fe3bf006e --- SDK/include/NDK/LuaAPI.hpp | 1 + SDK/include/NDK/LuaAPI.inl | 302 ++++++++++++++++++++++++++---- SDK/src/NDK/LuaAPI_Graphics.cpp | 32 ++++ SDK/src/NDK/LuaAPI_Math.cpp | 267 ++++++++++++++++++++++++++- SDK/src/NDK/LuaAPI_SDK.cpp | 313 ++++++++++++++++++++++++++++++++ 5 files changed, 872 insertions(+), 43 deletions(-) create mode 100644 SDK/src/NDK/LuaAPI_SDK.cpp diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index 3a420707b..2f3000034 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -28,6 +28,7 @@ namespace Ndk static void Register_Math(Nz::LuaInstance& instance); static void Register_Network(Nz::LuaInstance& instance); static void Register_Renderer(Nz::LuaInstance& instance); + static void Register_SDK(Nz::LuaInstance& instance); static void Register_Utility(Nz::LuaInstance& instance); }; } diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 4599d3f16..5b78a7e21 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -2,13 +2,222 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include +#include +#include #include +#include +#include +#include +#include #include +#ifndef NDK_SERVER +#include +#include +#endif + namespace Nz { + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Table: + angles->Set(instance.CheckField("pitch", index), instance.CheckField("yaw", index), instance.CheckField("roll", index)); + return 1; + + default: + { + if (instance.IsOfType(index, "EulerAngles")) + angles->Set(*(*static_cast(instance.ToUserdata(index)))); + else + angles->Set(*(*static_cast(instance.CheckUserdata(index, "Quaternion")))); + + return 1; + } + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesf* angles, TypeTag) + { + EulerAnglesd anglesDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &anglesDouble, TypeTag()); + + angles->Set(anglesDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaterniond* quat, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Table: + quat->Set(instance.CheckField("w", index), instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", index)); + return 1; + + default: + { + if (instance.IsOfType(index, "EulerAngles")) + quat->Set(*(*static_cast(instance.ToUserdata(index)))); + else + quat->Set(*(*static_cast(instance.CheckUserdata(index, "Quaternion")))); + + return 1; + } + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaternionf* quat, TypeTag) + { + Quaterniond quatDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &quatDouble, TypeTag()); + + quat->Set(quatDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, IpAddress* address, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_String: + address->BuildFromAddress(instance.CheckString(index)); + return 1; + + default: + *address = *(*static_cast(instance.CheckUserdata(index, "IpAddress"))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2d* vec, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Number: + if (index < 0 && index > -2) + instance.Error("Vector2 expected, two numbers are required to convert it"); + + vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1)); + return 2; + + case Nz::LuaType_Table: + vec->Set(instance.CheckField("x", index), instance.CheckField("y", index)); + return 1; + + default: + vec->Set(*(*static_cast(instance.CheckUserdata(index, "Vector2")))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2f* vec, TypeTag) + { + Vector2d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2ui* vec, TypeTag) + { + Vector2d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3d* vec, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Number: + if (index < 0 && index > -3) + instance.Error("Vector3 expected, three numbers are required to convert it"); + + vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1), instance.CheckNumber(index + 2)); + return 3; + + case Nz::LuaType_Table: + vec->Set(instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", index)); + return 1; + + default: + vec->Set(*(*static_cast(instance.CheckUserdata(index, "Vector3")))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3f* vec, TypeTag) + { + Vector3d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3ui* vec, TypeTag) + { + Vector3d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + +#ifndef NDK_SERVER + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, InstancedRenderableRef* renderable, TypeTag) + { + if (instance.IsOfType(index, "InstancedRenderable")) + *renderable = *(*static_cast(instance.CheckUserdata(index, "InstancedRenderable"))); + else + *renderable = *(*static_cast(instance.CheckUserdata(index, "Model"))); + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialParams* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->loadAlphaMap = instance.CheckField("LoadAlphaMap", params->loadAlphaMap); + params->loadDiffuseMap = instance.CheckField("LoadDiffuseMap", params->loadDiffuseMap); + params->loadEmissiveMap = instance.CheckField("LoadEmissiveMap", params->loadEmissiveMap); + params->loadHeightMap = instance.CheckField("LoadHeightMap", params->loadHeightMap); + params->loadNormalMap = instance.CheckField("LoadNormalMap", params->loadNormalMap); + params->loadSpecularMap = instance.CheckField("LoadSpecularMap", params->loadSpecularMap); + + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MeshParams* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->animated = instance.CheckField("Animated", params->animated); + params->center = instance.CheckField("Center", params->center); + params->flipUVs = instance.CheckField("FlipUVs", params->flipUVs); + params->optimizeIndexBuffers = instance.CheckField("OptimizeIndexBuffers", params->optimizeIndexBuffers); + params->scale = instance.CheckField("Scale", params->scale); + + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ModelParameters* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->loadMaterials = instance.CheckField("LoadMaterials", params->loadMaterials); + + LuaImplQueryArg(instance, -1, ¶ms->material, TypeTag()); + LuaImplQueryArg(instance, -1, ¶ms->mesh, TypeTag()); + + return 1; + } + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag) { instance.CheckType(index, Nz::LuaType_Table); @@ -17,50 +226,31 @@ namespace Nz return 1; } +#endif - inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3d* vec, TypeTag) + + + inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesd val, TypeTag) { - switch (lua.GetType(index)) - { - case Nz::LuaType_Number: - if (index < 0 && index > -3) - lua.Error("Vector3 expected, three numbers are required to convert it"); - - vec->Set(lua.CheckNumber(index), lua.CheckNumber(index + 1), lua.CheckNumber(index + 2)); - return 3; - - case Nz::LuaType_Table: - vec->Set(lua.CheckField("x", index), lua.CheckField("y", index), lua.CheckField("z", index)); - return 3; - - default: - vec->Set(*(*static_cast(lua.CheckUserdata(index, "Vector3")))); - return 1; - } + instance.PushInstance("EulerAngles", val); + return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3f* vec, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesf val, TypeTag) { - Vector3d vecDouble; - unsigned int ret = LuaImplQueryArg(lua, index, &vecDouble, TypeTag()); - - vec->Set(vecDouble); - return ret; + instance.PushInstance("EulerAngles", val); + return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3ui* vec, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, Quaterniond val, TypeTag) { - Vector3d vecDouble; - unsigned int ret = LuaImplQueryArg(lua, index, &vecDouble, TypeTag()); - - vec->Set(vecDouble); - return ret; + instance.PushInstance("Quaternion", val); + return 1; } - - inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, Quaternionf val, TypeTag) { - instance.PushInstance("SoundBuffer", val); + instance.PushInstance("Quaternion", val); return 1; } @@ -87,4 +277,48 @@ namespace Nz instance.PushInstance("Vector3", val); return 1; } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Entity* ptr, TypeTag) + { + instance.PushInstance("Entity", ptr); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle handle, TypeTag) + { + instance.PushInstance("Entity", handle); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::NodeComponentHandle handle, TypeTag) + { + instance.PushInstance("NodeComponent", handle); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag) + { + instance.PushInstance("World", ptr); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::WorldHandle handle, TypeTag) + { + instance.PushInstance("World", handle); + return 1; + } + +#ifndef NDK_SERVER + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle handle, TypeTag) + { + instance.PushInstance("GraphicsComponent", handle); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) + { + instance.PushInstance("SoundBuffer", val); + return 1; + } +#endif } diff --git a/SDK/src/NDK/LuaAPI_Graphics.cpp b/SDK/src/NDK/LuaAPI_Graphics.cpp index 08b68e853..5440b05a3 100644 --- a/SDK/src/NDK/LuaAPI_Graphics.cpp +++ b/SDK/src/NDK/LuaAPI_Graphics.cpp @@ -10,5 +10,37 @@ namespace Ndk { void LuaAPI::Register_Graphics(Nz::LuaInstance& instance) { + Nz::LuaClass instancedRenderable("InstancedRenderable"); + + Nz::LuaClass modelClass("Model"); + modelClass.Inherit(instancedRenderable, [] (Nz::ModelRef* model) -> Nz::InstancedRenderableRef* + { + return reinterpret_cast(model); //TODO: Make a ObjectRefCast + }); + + modelClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::ModelRef* + { + return new Nz::ModelRef(new Nz::Model); + }); + + //modelClass.SetMethod("GetMaterial", &Nz::Model::GetMaterial); + modelClass.SetMethod("GetMaterialCount", &Nz::Model::GetMaterialCount); + //modelClass.SetMethod("GetMesh", &Nz::Model::GetMesh); + modelClass.SetMethod("GetSkin", &Nz::Model::GetSkin); + modelClass.SetMethod("GetSkinCount", &Nz::Model::GetSkinCount); + + modelClass.SetMethod("IsAnimated", &Nz::Model::IsAnimated); + modelClass.SetMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); + + modelClass.SetMethod("Reset", &Nz::Model::Reset); + + //modelClass.SetMethod("SetMaterial", &Nz::Model::SetMaterial); + //modelClass.SetMethod("SetMesh", &Nz::Model::SetMesh); + //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); + modelClass.SetMethod("SetSkin", &Nz::Model::SetSkin); + modelClass.SetMethod("SetSkinCount", &Nz::Model::SetSkinCount); + + instancedRenderable.Register(instance); + modelClass.Register(instance); } } \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_Math.cpp b/SDK/src/NDK/LuaAPI_Math.cpp index 399610ee7..5887b7e83 100644 --- a/SDK/src/NDK/LuaAPI_Math.cpp +++ b/SDK/src/NDK/LuaAPI_Math.cpp @@ -8,6 +8,243 @@ namespace Ndk { void LuaAPI::Register_Math(Nz::LuaInstance& instance) { + /*********************************** Nz::EulerAngles **********************************/ + Nz::LuaClass eulerAnglesClass("EulerAngles"); + + eulerAnglesClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::EulerAnglesd* + { + unsigned int argCount = std::min(lua.GetStackTop(), 3U); + switch (argCount) + { + case 0: + return new Nz::EulerAnglesd(0.0, 0.0, 0.0); + + case 1: + return new Nz::EulerAnglesd(*(*static_cast(lua.CheckUserdata(1, "EulerAngles")))); + + case 3: + return new Nz::EulerAnglesd(lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3)); + } + + lua.Error("No matching overload for EulerAngles constructor"); + return nullptr; + }); + + eulerAnglesClass.SetMethod("__tostring", &Nz::EulerAnglesd::ToString); + + eulerAnglesClass.SetGetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) + { + std::size_t length; + const char* ypr = lua.CheckString(1, &length); + + switch (length) + { + case 1: + { + switch (ypr[0]) + { + case 'p': + lua.Push(instance.pitch); + return true; + + case 'y': + lua.Push(instance.yaw); + return true; + + case 'r': + lua.Push(instance.roll); + return true; + } + break; + } + + case 3: + { + if (std::memcmp(ypr, "yaw", 3) != 0) + break; + + lua.Push(instance.yaw); + return true; + } + + case 4: + { + if (std::memcmp(ypr, "roll", 4) != 0) + break; + + lua.Push(instance.roll); + return true; + } + + case 5: + { + if (std::memcmp(ypr, "pitch", 5) != 0) + break; + + lua.Push(instance.pitch); + return true; + } + } + + return false; + }); + + eulerAnglesClass.SetSetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) + { + std::size_t length; + const char* ypr = lua.CheckString(1, &length); + double value = lua.CheckNumber(2); + + switch (length) + { + case 1: + { + switch (ypr[0]) + { + case 'p': + instance.pitch = value; + return true; + + case 'y': + instance.yaw = value; + return true; + + case 'r': + instance.roll = value; + return true; + } + break; + } + + case 3: + { + if (std::memcmp(ypr, "yaw", 3) != 0) + break; + + instance.yaw = value; + return true; + } + + case 4: + { + if (std::memcmp(ypr, "roll", 4) != 0) + break; + + instance.roll = value; + return true; + } + + case 5: + { + if (std::memcmp(ypr, "pitch", 5) != 0) + break; + + instance.pitch = value; + return true; + } + } + + return false; + }); + + eulerAnglesClass.Register(instance); + + /*********************************** Nz::Quaternion **********************************/ + Nz::LuaClass quaternionClass("Quaternion"); + + quaternionClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Quaterniond* + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + switch (argCount) + { + case 0: + return new Nz::Quaterniond(1.0, 0.0, 0.0, 0.0); + + case 1: + { + if (lua.IsOfType(1, "EulerAngles")) + return new Nz::Quaterniond(*(*static_cast(lua.ToUserdata(1)))); + else if (lua.IsOfType(1, "Quaternion")) + return new Nz::Quaterniond(*(*static_cast(lua.ToUserdata(1)))); + } + + case 2: + return new Nz::Quaterniond(lua.CheckNumber(1), *(*static_cast(lua.CheckUserdata(2, "Vector3")))); + + case 4: + return new Nz::Quaterniond(lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3), lua.CheckNumber(4)); + } + + lua.Error("No matching overload for Quaternion constructor"); + return nullptr; + }); + + quaternionClass.SetMethod("__tostring", &Nz::Quaterniond::ToString); + + quaternionClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) + { + std::size_t length; + const char* wxyz = lua.CheckString(1, &length); + + if (length != 1) + return false; + + switch (wxyz[0]) + { + case 'w': + lua.Push(instance.w); + return true; + + case 'x': + lua.Push(instance.x); + return true; + + case 'y': + lua.Push(instance.y); + return true; + + case 'z': + lua.Push(instance.z); + return true; + } + + return false; + }); + + quaternionClass.SetSetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) + { + std::size_t length; + const char* wxyz = lua.CheckString(1, &length); + + if (length != 1) + return false; + + double value = lua.CheckNumber(2); + + switch (wxyz[0]) + { + case 'w': + instance.w = value; + return true; + + case 'x': + instance.x = value; + return true; + + case 'y': + instance.y = value; + return true; + + case 'z': + instance.z = value; + return true; + } + + return false; + }); + + quaternionClass.Register(instance); + /*********************************** Nz::Vector2 **********************************/ Nz::LuaClass vector2dClass("Vector2"); @@ -25,7 +262,7 @@ namespace Ndk if (lua.IsOfType(1, Nz::LuaType_Number)) return new Nz::Vector2d(lua.CheckNumber(1)); else if (lua.IsOfType(1, "Vector2")) - return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); + return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); break; } @@ -42,8 +279,14 @@ namespace Ndk switch (lua.GetType(1)) { case Nz::LuaType_Number: - lua.Push(instance[lua.CheckInteger(1)]); + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 2) + return false; + + lua.Push(instance[index - 1]); return true; + } case Nz::LuaType_String: { @@ -80,7 +323,7 @@ namespace Ndk if (index < 1 || index > 2) return false; - instance[index] = lua.CheckNumber(2); + instance[index - 1] = lua.CheckNumber(2); return true; } @@ -128,11 +371,11 @@ namespace Ndk case 1: { if (lua.IsOfType(1, Nz::LuaType_Number)) - return new Nz::Vector3d(lua.CheckNumber(1), *static_cast(lua.ToUserdata(1))); + return new Nz::Vector3d(lua.CheckNumber(1), *(*static_cast(lua.ToUserdata(1)))); else if (lua.IsOfType(1, "Vector2")) - return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); else if (lua.IsOfType(1, "Vector3")) - return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); break; } @@ -140,7 +383,7 @@ namespace Ndk case 2: { if (lua.IsOfType(1, Nz::LuaType_Number)) - return new Nz::Vector3d(lua.CheckNumber(1), *static_cast(lua.CheckUserdata(1, "Vector2"))); + return new Nz::Vector3d(lua.CheckNumber(1), *(*static_cast(lua.CheckUserdata(1, "Vector2")))); else if (lua.IsOfType(1, "Vector2")) return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1))), lua.CheckNumber(2)); @@ -159,8 +402,14 @@ namespace Ndk switch (lua.GetType(1)) { case Nz::LuaType_Number: - lua.Push(instance[lua.CheckInteger(1)]); + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 3) + return false; + + lua.Push(instance[index - 1]); return true; + } case Nz::LuaType_String: { @@ -201,7 +450,7 @@ namespace Ndk if (index < 1 || index > 3) return false; - instance[index] = lua.CheckNumber(2); + instance[index - 1] = lua.CheckNumber(2); return true; } diff --git a/SDK/src/NDK/LuaAPI_SDK.cpp b/SDK/src/NDK/LuaAPI_SDK.cpp new file mode 100644 index 000000000..50bd66005 --- /dev/null +++ b/SDK/src/NDK/LuaAPI_SDK.cpp @@ -0,0 +1,313 @@ +// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + + +#include +#include +#include +#include +#include +#include + +namespace Ndk +{ + namespace + { + int AddNilComponent(Nz::LuaInstance& lua, EntityHandle&) + { + lua.PushNil(); + return 1; + } + + template + int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle) + { + static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + + T& component = handle->AddComponent(); + lua.Push(component.CreateHandle()); + return 1; + } + + int AddComponent(Nz::LuaInstance& lua, EntityHandle& handle, ComponentIndex index) + { + std::vector componentAdder(BaseComponent::GetMaxComponentIndex(), AddNilComponent); + componentAdder[GraphicsComponent::componentIndex] = &AddComponentOfType; + componentAdder[NodeComponent::componentIndex] = &AddComponentOfType; + + if (index > componentAdder.size()) + { + lua.Error("Invalid component index"); + return 0; + } + + return componentAdder[index](lua, handle); + } + + int PushNilComponent(Nz::LuaInstance& lua, BaseComponent&) + { + lua.PushNil(); + return 1; + } + + template + int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component) + { + static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + + T& rightComponent = static_cast(component); + lua.Push(rightComponent.CreateHandle()); + return 1; + } + + int PushComponent(Nz::LuaInstance& lua, BaseComponent& component) + { + std::vector componentConverter(BaseComponent::GetMaxComponentIndex(), PushNilComponent); + componentConverter[GraphicsComponent::componentIndex] = &PushComponentOfType; + componentConverter[NodeComponent::componentIndex] = &PushComponentOfType; + + ComponentIndex index = component.GetIndex(); + + if (index > componentConverter.size()) + { + lua.Error("Invalid component index"); + return 0; + } + + return componentConverter[index](lua, component); + } + } + + void LuaAPI::Register_SDK(Nz::LuaInstance& instance) + { + Nz::LuaClass graphicsComponent("GraphicsComponent"); + + graphicsComponent.SetMethod("Attach", &GraphicsComponent::Attach, 0); + + graphicsComponent.Register(instance); + + Nz::LuaClass nodeClass("Node"); //< TODO: Move to Utility + + nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); + //nodeClass.SetMethod("GetChilds", &Nz::Node::GetChilds); + nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); + nodeClass.SetMethod("GetForward", &Nz::Node::GetForward); + nodeClass.SetMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); + nodeClass.SetMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); + nodeClass.SetMethod("GetInheritScale", &Nz::Node::GetInheritScale); + nodeClass.SetMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); + //nodeClass.SetMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); + nodeClass.SetMethod("GetInitialScale", &Nz::Node::GetInitialScale); + nodeClass.SetMethod("GetLeft", &Nz::Node::GetLeft); + nodeClass.SetMethod("GetNodeType", &Nz::Node::GetNodeType); + //nodeClass.SetMethod("GetParent", &Nz::Node::GetParent); + nodeClass.SetMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); + nodeClass.SetMethod("GetRight", &Nz::Node::GetRight); + //nodeClass.SetMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); + nodeClass.SetMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); + //nodeClass.SetMethod("GetTransformMatrix", &Nz::Node::GetTransformMatrix); + nodeClass.SetMethod("GetUp", &Nz::Node::GetUp); + + nodeClass.SetMethod("HasChilds", &Nz::Node::HasChilds); + + nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); + nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); + nodeClass.SetMethod("GetForward", &Nz::Node::GetForward); + nodeClass.SetMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); + nodeClass.SetMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); + nodeClass.SetMethod("GetInheritScale", &Nz::Node::GetInheritScale); + nodeClass.SetMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); + nodeClass.SetMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); + nodeClass.SetMethod("GetInitialScale", &Nz::Node::GetInitialScale); + nodeClass.SetMethod("GetLeft", &Nz::Node::GetLeft); + nodeClass.SetMethod("GetNodeType", &Nz::Node::GetNodeType); + nodeClass.SetMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); + nodeClass.SetMethod("GetRight", &Nz::Node::GetRight); + nodeClass.SetMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); + nodeClass.SetMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); + nodeClass.SetMethod("GetUp", &Nz::Node::GetUp); + + nodeClass.SetMethod("SetInitialPosition", (void(Nz::Node::*)(const Nz::Vector3f&)) &Nz::Node::SetInitialPosition); + nodeClass.SetMethod("SetInitialRotation", (void(Nz::Node::*)(const Nz::Quaternionf&)) &Nz::Node::SetInitialRotation); + + nodeClass.SetMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local); + nodeClass.SetMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local); + + nodeClass.SetMethod("Move", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + int argIndex = 1; + + Nz::Vector3f offset = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + node.Move(offset, coordSys); + + return 0; + }); + + nodeClass.SetMethod("Rotate", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + int argIndex = 1; + + Nz::Quaternionf rotation = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + node.Rotate(rotation, coordSys); + + return 0; + }); + + nodeClass.SetMethod("Scale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + + int argIndex = 1; + switch (argCount) + { + case 1: + { + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + node.Scale(lua.Check(&argIndex)); + else + node.Scale(lua.Check(&argIndex)); + + return 0; + } + + case 3: + node.Scale(lua.Check(&argIndex)); + return 0; + } + + lua.Error("No matching overload for method Scale"); + return 0; + }); + + nodeClass.SetMethod("SetScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + + int argIndex = 1; + switch (argCount) + { + case 1: + case 2: + { + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + float scale = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + node.SetScale(scale, coordSys); + } + else + node.SetScale(lua.Check(&argIndex)); + + return 0; + } + + case 3: + case 4: + { + Nz::Vector3f scale = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + + node.SetScale(scale, coordSys); + return 0; + } + } + + lua.Error("No matching overload for method SetScale"); + return 0; + }); + + nodeClass.SetMethod("SetInitialScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + + int argIndex = 1; + switch (argCount) + { + case 1: + { + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + node.SetInitialScale(lua.Check(&argIndex)); + else + node.SetInitialScale(lua.Check(&argIndex)); + + return 0; + } + + case 2: + case 3: + node.SetInitialScale(lua.Check(&argIndex)); + return 0; + } + + lua.Error("No matching overload for method SetInitialScale"); + return 0; + }); + + nodeClass.Register(instance); + + Nz::LuaClass nodeComponent("NodeComponent"); + nodeComponent.Inherit(nodeClass, [] (NodeComponentHandle* handle) -> Nz::Node* + { + return handle->GetObject(); + }); + + nodeComponent.Register(instance); + + Nz::LuaClass entityClass("Entity"); + + entityClass.SetMethod("Enable", &Entity::Enable); + entityClass.SetMethod("GetId", &Entity::GetId); + entityClass.SetMethod("GetWorld", &Entity::GetWorld); + entityClass.SetMethod("Kill", &Entity::Kill); + entityClass.SetMethod("IsEnabled", &Entity::IsEnabled); + entityClass.SetMethod("IsValid", &Entity::IsValid); + entityClass.SetMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); + entityClass.SetMethod("RemoveAllComponents", &Entity::RemoveAllComponents); + entityClass.SetMethod("__tostring", &EntityHandle::ToString); + + entityClass.SetMethod("AddComponent", [] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + { + int index = 1; + ComponentIndex componentIndex = lua.Check(&index); + + return AddComponent(lua, handle, componentIndex); + }); + + entityClass.SetMethod("GetComponent", [] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + { + int index = 1; + ComponentIndex componentIndex = lua.Check(&index); + + if (!handle->HasComponent(componentIndex)) + { + lua.PushNil(); + return 1; + } + + return PushComponent(lua, handle->GetComponent(componentIndex)); + }); + + entityClass.Register(instance); + + Nz::LuaClass worldClass("World"); + + worldClass.SetMethod("CreateEntity", &World::CreateEntity); + worldClass.SetMethod("CreateEntities", &World::CreateEntities); + worldClass.SetMethod("Clear", &World::Clear); + + worldClass.Register(instance); + + instance.PushTable(0, 2); + { + instance.PushInteger(GraphicsComponent::componentIndex); + instance.SetField("Graphics"); + + instance.PushInteger(NodeComponent::componentIndex); + instance.SetField("Node"); + } + instance.SetGlobal("ComponentType"); + } +} \ No newline at end of file From 6808d60cc163ee4fe95bb55a91f63d2d84b75af9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 31 Mar 2016 22:51:10 +0200 Subject: [PATCH 192/229] Sdk: Remake LuaAPI internal Former-commit-id: 297c30dbeca443d934edfd8d889cd7a6c725d0e1 --- SDK/include/NDK/LuaAPI.hpp | 18 +- SDK/src/NDK/LuaAPI.cpp | 31 +++ SDK/src/NDK/LuaAPI_Utility.cpp | 97 --------- SDK/src/NDK/LuaBinding.cpp | 76 +++++++ SDK/src/NDK/LuaBinding.hpp | 114 ++++++++++ ...{LuaAPI_Audio.cpp => LuaBinding_Audio.cpp} | 16 +- .../{LuaAPI_Core.cpp => LuaBinding_Core.cpp} | 45 ++-- ...I_Graphics.cpp => LuaBinding_Graphics.cpp} | 13 +- .../{LuaAPI_Math.cpp => LuaBinding_Math.cpp} | 26 +-- ...API_Network.cpp => LuaBinding_Network.cpp} | 47 ++-- ...I_Renderer.cpp => LuaBinding_Renderer.cpp} | 10 +- SDK/src/NDK/LuaBinding_SDK.cpp | 173 +++++++++++++++ ...{LuaAPI_SDK.cpp => LuaBinding_Utility.cpp} | 204 +++++++----------- build/scripts/tools/ndk.lua | 3 +- build/scripts/tools/ndk_server.lua | 9 +- 15 files changed, 553 insertions(+), 329 deletions(-) create mode 100644 SDK/src/NDK/LuaAPI.cpp delete mode 100644 SDK/src/NDK/LuaAPI_Utility.cpp create mode 100644 SDK/src/NDK/LuaBinding.cpp create mode 100644 SDK/src/NDK/LuaBinding.hpp rename SDK/src/NDK/{LuaAPI_Audio.cpp => LuaBinding_Audio.cpp} (96%) rename SDK/src/NDK/{LuaAPI_Core.cpp => LuaBinding_Core.cpp} (92%) rename SDK/src/NDK/{LuaAPI_Graphics.cpp => LuaBinding_Graphics.cpp} (82%) rename SDK/src/NDK/{LuaAPI_Math.cpp => LuaBinding_Math.cpp} (96%) rename SDK/src/NDK/{LuaAPI_Network.cpp => LuaBinding_Network.cpp} (82%) rename SDK/src/NDK/{LuaAPI_Renderer.cpp => LuaBinding_Renderer.cpp} (64%) create mode 100644 SDK/src/NDK/LuaBinding_SDK.cpp rename SDK/src/NDK/{LuaAPI_SDK.cpp => LuaBinding_Utility.cpp} (56%) diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index 2f3000034..277948bd5 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -16,20 +16,22 @@ namespace Nz namespace Ndk { + class LuaBinding; + class NDK_API LuaAPI { public: LuaAPI() = delete; ~LuaAPI() = delete; - static void Register_Audio(Nz::LuaInstance& instance); - static void Register_Core(Nz::LuaInstance& instance); - static void Register_Graphics(Nz::LuaInstance& instance); - static void Register_Math(Nz::LuaInstance& instance); - static void Register_Network(Nz::LuaInstance& instance); - static void Register_Renderer(Nz::LuaInstance& instance); - static void Register_SDK(Nz::LuaInstance& instance); - static void Register_Utility(Nz::LuaInstance& instance); + static bool Initialize(); + + static void RegisterClasses(Nz::LuaInstance& instance); + + static void Uninitialize(); + + private: + static LuaBinding* s_binding; }; } diff --git a/SDK/src/NDK/LuaAPI.cpp b/SDK/src/NDK/LuaAPI.cpp new file mode 100644 index 000000000..a1b84bf5d --- /dev/null +++ b/SDK/src/NDK/LuaAPI.cpp @@ -0,0 +1,31 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include +#include + +namespace Ndk +{ + bool LuaAPI::Initialize() + { + s_binding = new LuaBinding; + return true; + } + + void LuaAPI::RegisterClasses(Nz::LuaInstance& instance) + { + if (!s_binding && !Initialize()) + { + NazaraError("Failed to initialize binding"); + return; + } + + s_binding->RegisterClasses(instance); + } + + void LuaAPI::Uninitialize() + { + delete s_binding; + } + + LuaBinding* LuaAPI::s_binding = nullptr; +} diff --git a/SDK/src/NDK/LuaAPI_Utility.cpp b/SDK/src/NDK/LuaAPI_Utility.cpp deleted file mode 100644 index 0f2659e1e..000000000 --- a/SDK/src/NDK/LuaAPI_Utility.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// This file is part of the "Nazara Development Kit" -// For conditions of distribution and use, see copyright notice in Prerequesites.hpp - - -#include -#include -#include - -namespace Ndk -{ - void LuaAPI::Register_Utility(Nz::LuaInstance& instance) - { - /*********************************** Nz::AbstractImage **********************************/ - Nz::LuaClass abstractImage("AbstractImage"); - - abstractImage.SetMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); - abstractImage.SetMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); - abstractImage.SetMethod("GetFormat", &Nz::AbstractImage::GetFormat); - abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); - abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); - abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); - abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); - abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); - abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); - abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); - abstractImage.SetMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); - - abstractImage.SetMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int - { - unsigned int argCount = std::min(lua.GetStackTop(), 1U); - switch (argCount) - { - case 0: - return lua.Push(abstractImage->GetMemoryUsage()); - - case 1: - { - int index = 1; - Nz::UInt8 level(lua.Check(&index)); - - return lua.Push(abstractImage->GetMemoryUsage(level)); - } - } - - lua.Error("No matching overload for method GetMemoryUsage"); - return 0; - }); - - abstractImage.SetMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int - { - unsigned int argCount = std::min(lua.GetStackTop(), 6U); - int argIndex = 1; - - std::size_t bufferSize = 0; - const Nz::UInt8* pixels = reinterpret_cast(lua.CheckString(argIndex++, &bufferSize)); - - if (argCount < 2 || lua.IsOfType(2, Nz::LuaType_Number)) - { - // bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) - unsigned int srcWidth = lua.Check(&argIndex, 0); - unsigned int srcHeight = lua.Check(&argIndex, 0); - Nz::UInt8 level = lua.Check(&argIndex, 0); - - ///TODO: Buffer checks (Nz::ByteBufferView ?) - return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); - } - /* Disabled until Box and Rect have been ported - else if (lua.IsOfType(2, "Box")) - { - // bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) - Nz::Boxui box = lua.Check(&argIndex); - unsigned int srcWidth = lua.Check(&argIndex, 0); - unsigned int srcHeight = lua.Check(&argIndex, 0); - Nz::UInt8 level = lua.Check(&argIndex, 0); - - ///TODO: Buffer checks (Nz::ByteBufferView ?) - return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); - } - else if (lua.IsOfType(2, "Rect")) - { - // bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) - Nz::Rectui box = lua.Check(&argIndex); - unsigned int srcWidth = lua.Check(&argIndex, 0); - unsigned int srcHeight = lua.Check(&argIndex, 0); - Nz::UInt8 level = lua.Check(&argIndex, 0); - - ///TODO: Buffer checks (Nz::ByteBufferView ?) - return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); - }*/ - - lua.Error("No matching overload for method Update"); - return 0; - }); - - abstractImage.Register(instance); - } -} \ No newline at end of file diff --git a/SDK/src/NDK/LuaBinding.cpp b/SDK/src/NDK/LuaBinding.cpp new file mode 100644 index 000000000..0c2766ca7 --- /dev/null +++ b/SDK/src/NDK/LuaBinding.cpp @@ -0,0 +1,76 @@ +// This file was automatically generated on 26 May 2014 at 01:05:31 + +#include + +namespace Ndk +{ + LuaBinding::LuaBinding() : + // Core + clockClass("Clock"), + directoryClass("Directory"), + fileClass("File"), + streamClass("Stream"), + + // Math + eulerAnglesClass("EulerAngles"), + quaternionClass("Quaternion"), + vector2dClass("Vector2"), + vector3dClass("Vector3"), + + // Network + abstractSocketClass("AbstractSocket"), + ipAddressClass("IpAddress"), + + // Utility + abstractImage("AbstractImage"), + nodeClass("Node"), + + // SDK + nodeComponent("NodeComponent"), + entityClass("Entity"), + worldClass("World") + + #ifndef NDK_SERVER + , + + // Audio + soundBuffer("SoundBuffer"), + soundEmitter("SoundEmitter"), + soundClass("Sound"), + + // Graphics + instancedRenderable("InstancedRenderable"), + modelClass("Model"), + + // SDK + graphicsComponent("GraphicsComponent") + #endif + { + BindCore(); + BindMath(); + BindNetwork(); + BindSDK(); + BindUtility(); + + #ifndef NDK_SERVER + BindAudio(); + BindGraphics(); + BindRenderer(); + #endif + } + + void LuaBinding::RegisterClasses(Nz::LuaInstance& instance) + { + RegisterCore(instance); + RegisterMath(instance); + RegisterNetwork(instance); + RegisterSDK(instance); + RegisterUtility(instance); + + #ifndef NDK_SERVER + RegisterAudio(instance); + RegisterGraphics(instance); + RegisterRenderer(instance); + #endif + } +} diff --git a/SDK/src/NDK/LuaBinding.hpp b/SDK/src/NDK/LuaBinding.hpp new file mode 100644 index 000000000..c8dda3c2f --- /dev/null +++ b/SDK/src/NDK/LuaBinding.hpp @@ -0,0 +1,114 @@ +// 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_LUABINDING_HPP +#define NDK_LUABINDING_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef NDK_SERVER +#include +#include +#include +#endif + +namespace Ndk +{ + class LuaBinding + { + public: + LuaBinding(); + ~LuaBinding() = default; + + void RegisterClasses(Nz::LuaInstance& instance); + + private: + void BindCore(); + void BindMath(); + void BindNetwork(); + void BindSDK(); + void BindUtility(); + + template void EnableComponentBinding(); + + void RegisterCore(Nz::LuaInstance& instance); + void RegisterMath(Nz::LuaInstance& instance); + void RegisterNetwork(Nz::LuaInstance& instance); + void RegisterSDK(Nz::LuaInstance& instance); + void RegisterUtility(Nz::LuaInstance& instance); + + #ifndef NDK_SERVER + void BindAudio(); + void BindGraphics(); + void BindRenderer(); + + void RegisterAudio(Nz::LuaInstance& instance); + void RegisterGraphics(Nz::LuaInstance& instance); + void RegisterRenderer(Nz::LuaInstance& instance); + #endif + + // Core + Nz::LuaClass clockClass; + Nz::LuaClass directoryClass; + Nz::LuaClass fileClass; + Nz::LuaClass streamClass; + + // Math + Nz::LuaClass eulerAnglesClass; + Nz::LuaClass quaternionClass; + Nz::LuaClass vector2dClass; + Nz::LuaClass vector3dClass; + + // Network + Nz::LuaClass abstractSocketClass; + Nz::LuaClass ipAddressClass; + + // Utility + Nz::LuaClass abstractImage; + Nz::LuaClass nodeClass; + + // SDK + Nz::LuaClass entityClass; + Nz::LuaClass nodeComponent; + Nz::LuaClass worldClass; + + using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); + using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); + + struct ComponentBinding + { + AddComponentFunc adder; + GetComponentFunc getter; + bool valid = false; + }; + + std::vector m_componentBinding; + + #ifndef NDK_SERVER + // Audio + Nz::LuaClass soundClass; + Nz::LuaClass soundBuffer; + Nz::LuaClass soundEmitter; + + // Graphics + Nz::LuaClass instancedRenderable; + Nz::LuaClass modelClass; + + // SDK + Nz::LuaClass graphicsComponent; + #endif + }; +} + +#endif // NDK_LUABINDING_HPP diff --git a/SDK/src/NDK/LuaAPI_Audio.cpp b/SDK/src/NDK/LuaBinding_Audio.cpp similarity index 96% rename from SDK/src/NDK/LuaAPI_Audio.cpp rename to SDK/src/NDK/LuaBinding_Audio.cpp index abe5638d4..a894595b3 100644 --- a/SDK/src/NDK/LuaAPI_Audio.cpp +++ b/SDK/src/NDK/LuaBinding_Audio.cpp @@ -1,16 +1,13 @@ // This file was automatically generated on 26 May 2014 at 01:05:31 +#include #include -#include -#include namespace Ndk { - void LuaAPI::Register_Audio(Nz::LuaInstance& instance) + void LuaBinding::BindAudio() { /*********************************** Nz::SoundBuffer **********************************/ - Nz::LuaClass soundBuffer("SoundBuffer"); - soundBuffer.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::SoundBufferRef* { return new Nz::SoundBufferRef(new Nz::SoundBuffer); @@ -65,8 +62,6 @@ namespace Ndk return 1; }); - soundBuffer.Register(instance); - /*********************************** Nz::SoundEmitter **********************************/ Nz::LuaClass soundEmitter("SoundEmitter"); @@ -93,8 +88,6 @@ namespace Ndk soundEmitter.SetMethod("SetVolume", &Nz::SoundEmitter::SetVolume); soundEmitter.SetMethod("Stop", &Nz::SoundEmitter::Stop); - soundEmitter.Register(instance); - /*********************************** Nz::Sound **********************************/ Nz::LuaClass soundClass("Sound"); soundClass.Inherit(soundEmitter); @@ -122,7 +115,12 @@ namespace Ndk lua.PushString(stream); return 1; }); + } + void LuaBinding::RegisterAudio(Nz::LuaInstance& instance) + { soundClass.Register(instance); + soundBuffer.Register(instance); + soundEmitter.Register(instance); } } diff --git a/SDK/src/NDK/LuaAPI_Core.cpp b/SDK/src/NDK/LuaBinding_Core.cpp similarity index 92% rename from SDK/src/NDK/LuaAPI_Core.cpp rename to SDK/src/NDK/LuaBinding_Core.cpp index 7529e4eae..8ed8682ce 100644 --- a/SDK/src/NDK/LuaAPI_Core.cpp +++ b/SDK/src/NDK/LuaBinding_Core.cpp @@ -1,18 +1,13 @@ // This file was automatically generated on 26 May 2014 at 01:05:31 +#include #include -#include -#include - -#include namespace Ndk { - void LuaAPI::Register_Core(Nz::LuaInstance& instance) + void LuaBinding::BindCore() { /*********************************** Nz::Clock **********************************/ - Nz::LuaClass clockClass("Clock"); - clockClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Clock* { int argIndex = 1; @@ -39,12 +34,7 @@ namespace Ndk return 1; }); - - clockClass.Register(instance); - /********************************* Nz::Directory ********************************/ - Nz::LuaClass directoryClass("Directory"); - directoryClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Directory* { unsigned int argCount = std::min(lua.GetStackTop(), 1U); @@ -93,12 +83,7 @@ namespace Ndk return 1; }); - - directoryClass.Register(instance); - /*********************************** Nz::Stream ***********************************/ - Nz::LuaClass streamClass("Stream"); - streamClass.SetMethod("EnableTextMode", &Nz::Stream::EnableTextMode); streamClass.SetMethod("Flush", &Nz::Stream::Flush); streamClass.SetMethod("GetCursorPos", &Nz::Stream::GetCursorPos); @@ -139,10 +124,7 @@ namespace Ndk return 1; }); - streamClass.Register(instance); - /*********************************** Nz::File ***********************************/ - Nz::LuaClass fileClass("File"); fileClass.Inherit(streamClass); fileClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::File* @@ -242,8 +224,15 @@ namespace Ndk lua.PushString(stream); return 1; }); + } + void LuaBinding::RegisterCore(Nz::LuaInstance& instance) + { + // Classes + clockClass.Register(instance); + directoryClass.Register(instance); fileClass.Register(instance); + streamClass.Register(instance); // Enums @@ -251,9 +240,9 @@ namespace Ndk static_assert(Nz::CursorPosition_Max + 1 == 3, "Nz::CursorPosition has been updated but change was not reflected to Lua binding"); instance.PushTable(0, 3); { - instance.SetField("AtBegin", Nz::CursorPosition_AtBegin); + instance.SetField("AtBegin", Nz::CursorPosition_AtBegin); instance.SetField("AtCurrent", Nz::CursorPosition_AtCurrent); - instance.SetField("AtEnd", Nz::CursorPosition_AtEnd); + instance.SetField("AtEnd", Nz::CursorPosition_AtEnd); } instance.SetGlobal("CursorPosition"); @@ -277,13 +266,13 @@ namespace Ndk static_assert(Nz::OpenMode_Max + 1 == 2 * (64), "Nz::OpenModeFlags has been updated but change was not reflected to Lua binding"); instance.PushTable(0, 8); { - instance.SetField("Append", Nz::OpenMode_Append); - instance.SetField("NotOpen", Nz::OpenMode_NotOpen); - instance.SetField("Lock", Nz::OpenMode_Lock); - instance.SetField("ReadOnly", Nz::OpenMode_ReadOnly); + instance.SetField("Append", Nz::OpenMode_Append); + instance.SetField("NotOpen", Nz::OpenMode_NotOpen); + instance.SetField("Lock", Nz::OpenMode_Lock); + instance.SetField("ReadOnly", Nz::OpenMode_ReadOnly); instance.SetField("ReadWrite", Nz::OpenMode_ReadWrite); - instance.SetField("Text", Nz::OpenMode_Text); - instance.SetField("Truncate", Nz::OpenMode_Truncate); + instance.SetField("Text", Nz::OpenMode_Text); + instance.SetField("Truncate", Nz::OpenMode_Truncate); instance.SetField("WriteOnly", Nz::OpenMode_WriteOnly); } instance.SetGlobal("OpenMode"); diff --git a/SDK/src/NDK/LuaAPI_Graphics.cpp b/SDK/src/NDK/LuaBinding_Graphics.cpp similarity index 82% rename from SDK/src/NDK/LuaAPI_Graphics.cpp rename to SDK/src/NDK/LuaBinding_Graphics.cpp index 5440b05a3..e3bbaec66 100644 --- a/SDK/src/NDK/LuaAPI_Graphics.cpp +++ b/SDK/src/NDK/LuaBinding_Graphics.cpp @@ -1,18 +1,16 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp - +#include #include -#include -#include namespace Ndk { - void LuaAPI::Register_Graphics(Nz::LuaInstance& instance) + void LuaBinding::BindGraphics() { - Nz::LuaClass instancedRenderable("InstancedRenderable"); + /*********************************** Nz::InstancedRenderable ***********************************/ - Nz::LuaClass modelClass("Model"); + /*********************************** Nz::Model ***********************************/ modelClass.Inherit(instancedRenderable, [] (Nz::ModelRef* model) -> Nz::InstancedRenderableRef* { return reinterpret_cast(model); //TODO: Make a ObjectRefCast @@ -39,7 +37,10 @@ namespace Ndk //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); modelClass.SetMethod("SetSkin", &Nz::Model::SetSkin); modelClass.SetMethod("SetSkinCount", &Nz::Model::SetSkinCount); + } + void LuaBinding::RegisterGraphics(Nz::LuaInstance& instance) + { instancedRenderable.Register(instance); modelClass.Register(instance); } diff --git a/SDK/src/NDK/LuaAPI_Math.cpp b/SDK/src/NDK/LuaBinding_Math.cpp similarity index 96% rename from SDK/src/NDK/LuaAPI_Math.cpp rename to SDK/src/NDK/LuaBinding_Math.cpp index 5887b7e83..5d7bc5a6b 100644 --- a/SDK/src/NDK/LuaAPI_Math.cpp +++ b/SDK/src/NDK/LuaBinding_Math.cpp @@ -1,16 +1,14 @@ // This file was automatically generated on 26 May 2014 at 01:05:31 +#include #include -#include -#include +#include namespace Ndk { - void LuaAPI::Register_Math(Nz::LuaInstance& instance) + void LuaBinding::BindMath() { /*********************************** Nz::EulerAngles **********************************/ - Nz::LuaClass eulerAnglesClass("EulerAngles"); - eulerAnglesClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::EulerAnglesd* { unsigned int argCount = std::min(lua.GetStackTop(), 3U); @@ -147,11 +145,7 @@ namespace Ndk return false; }); - eulerAnglesClass.Register(instance); - /*********************************** Nz::Quaternion **********************************/ - Nz::LuaClass quaternionClass("Quaternion"); - quaternionClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Quaterniond* { unsigned int argCount = std::min(lua.GetStackTop(), 4U); @@ -243,11 +237,7 @@ namespace Ndk return false; }); - quaternionClass.Register(instance); - /*********************************** Nz::Vector2 **********************************/ - Nz::LuaClass vector2dClass("Vector2"); - vector2dClass.SetConstructor([](Nz::LuaInstance& lua) -> Nz::Vector2d* { unsigned int argCount = std::min(lua.GetStackTop(), 2U); @@ -354,11 +344,7 @@ namespace Ndk return false; }); - vector2dClass.Register(instance); - /*********************************** Nz::Vector3 **********************************/ - Nz::LuaClass vector3dClass("Vector3"); - vector3dClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Vector3d* { unsigned int argCount = std::min(lua.GetStackTop(), 3U); @@ -484,7 +470,13 @@ namespace Ndk return false; }); + } + void LuaBinding::RegisterMath(Nz::LuaInstance& instance) + { + eulerAnglesClass.Register(instance); + quaternionClass.Register(instance); + vector2dClass.Register(instance); vector3dClass.Register(instance); } } diff --git a/SDK/src/NDK/LuaAPI_Network.cpp b/SDK/src/NDK/LuaBinding_Network.cpp similarity index 82% rename from SDK/src/NDK/LuaAPI_Network.cpp rename to SDK/src/NDK/LuaBinding_Network.cpp index e5a36ac7d..14f0b12ca 100644 --- a/SDK/src/NDK/LuaAPI_Network.cpp +++ b/SDK/src/NDK/LuaBinding_Network.cpp @@ -1,28 +1,22 @@ // This file was automatically generated on 26 May 2014 at 01:05:31 +#include #include -#include -#include namespace Ndk { - void LuaAPI::Register_Network(Nz::LuaInstance& instance) + void LuaBinding::BindNetwork() { /*********************************** Nz::AbstractSocket **********************************/ - Nz::LuaClass abstractSocketClass("AbstractSocket"); - - abstractSocketClass.SetMethod("Close", &Nz::AbstractSocket::Close); - abstractSocketClass.SetMethod("EnableBlocking", &Nz::AbstractSocket::EnableBlocking); - abstractSocketClass.SetMethod("GetLastError", &Nz::AbstractSocket::GetLastError); - abstractSocketClass.SetMethod("GetState", &Nz::AbstractSocket::GetState); - abstractSocketClass.SetMethod("GetType", &Nz::AbstractSocket::GetType); - abstractSocketClass.SetMethod("IsBlockingEnabled", &Nz::AbstractSocket::IsBlockingEnabled); + abstractSocketClass.SetMethod("Close", &Nz::AbstractSocket::Close); + abstractSocketClass.SetMethod("EnableBlocking", &Nz::AbstractSocket::EnableBlocking); + abstractSocketClass.SetMethod("GetLastError", &Nz::AbstractSocket::GetLastError); + abstractSocketClass.SetMethod("GetState", &Nz::AbstractSocket::GetState); + abstractSocketClass.SetMethod("GetType", &Nz::AbstractSocket::GetType); + abstractSocketClass.SetMethod("IsBlockingEnabled", &Nz::AbstractSocket::IsBlockingEnabled); abstractSocketClass.SetMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes); - abstractSocketClass.Register(instance); - - Nz::LuaClass ipAddressClass("IpAddress"); - + /*********************************** Nz::IpAddress **********************************/ ipAddressClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::IpAddress* { unsigned int argCount = std::min(lua.GetStackTop(), 9U); @@ -43,18 +37,18 @@ namespace Ndk case 8: case 9: return new Nz::IpAddress(lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), - lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex, 0)); + lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex), lua.Check(&argIndex, 0)); } return nullptr; }); - ipAddressClass.SetMethod("GetPort", &Nz::IpAddress::GetPort); + ipAddressClass.SetMethod("GetPort", &Nz::IpAddress::GetPort); ipAddressClass.SetMethod("GetProtocol", &Nz::IpAddress::GetProtocol); - ipAddressClass.SetMethod("IsLoopback", &Nz::IpAddress::IsLoopback); - ipAddressClass.SetMethod("IsValid", &Nz::IpAddress::IsValid); - ipAddressClass.SetMethod("ToUInt32", &Nz::IpAddress::ToUInt32); - ipAddressClass.SetMethod("__tostring", &Nz::IpAddress::ToString); + ipAddressClass.SetMethod("IsLoopback", &Nz::IpAddress::IsLoopback); + ipAddressClass.SetMethod("IsValid", &Nz::IpAddress::IsValid); + ipAddressClass.SetMethod("ToUInt32", &Nz::IpAddress::ToUInt32); + ipAddressClass.SetMethod("__tostring", &Nz::IpAddress::ToString); ipAddressClass.SetStaticMethod("ResolveAddress", [] (Nz::LuaInstance& instance) -> int { @@ -96,10 +90,10 @@ namespace Ndk { instance.PushInteger(index++); instance.PushTable(0, 4); - instance.SetField("Address", std::move(info.address)); + instance.SetField("Address", std::move(info.address)); instance.SetField("CanonicalName", std::move(info.canonicalName)); - instance.SetField("Protocol", std::move(info.protocol)); - instance.SetField("SocketType", std::move(info.socketType)); + instance.SetField("Protocol", std::move(info.protocol)); + instance.SetField("SocketType", std::move(info.socketType)); instance.SetTable(); } @@ -112,7 +106,12 @@ namespace Ndk return 2; } }); + } + void LuaBinding::RegisterNetwork(Nz::LuaInstance& instance) + { + // Classes + abstractSocketClass.Register(instance); ipAddressClass.Register(instance); // Enums diff --git a/SDK/src/NDK/LuaAPI_Renderer.cpp b/SDK/src/NDK/LuaBinding_Renderer.cpp similarity index 64% rename from SDK/src/NDK/LuaAPI_Renderer.cpp rename to SDK/src/NDK/LuaBinding_Renderer.cpp index cbbd24b92..78b9fe561 100644 --- a/SDK/src/NDK/LuaAPI_Renderer.cpp +++ b/SDK/src/NDK/LuaBinding_Renderer.cpp @@ -2,14 +2,16 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp - +#include #include -#include -#include namespace Ndk { - void LuaAPI::Register_Renderer(Nz::LuaInstance& instance) + void LuaBinding::BindRenderer() + { + } + + void LuaBinding::RegisterRenderer(Nz::LuaInstance& instance) { } } \ No newline at end of file diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp new file mode 100644 index 000000000..bb8ec3475 --- /dev/null +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -0,0 +1,173 @@ +// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include + +namespace Ndk +{ + namespace + { + int AddNilComponent(Nz::LuaInstance& lua, EntityHandle&) + { + lua.PushNil(); + return 1; + } + + template + int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle) + { + static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + + T& component = handle->AddComponent(); + lua.Push(component.CreateHandle()); + return 1; + } + + int PushNilComponent(Nz::LuaInstance& lua, BaseComponent&) + { + lua.PushNil(); + return 1; + } + + template + int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component) + { + static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + + T& rightComponent = static_cast(component); + lua.Push(rightComponent.CreateHandle()); + return 1; + } + } + + void LuaBinding::BindSDK() + { + /*********************************** Ndk::NodeComponent **********************************/ + nodeComponent.Inherit(nodeClass, [] (NodeComponentHandle* handle) -> Nz::Node* + { + return handle->GetObject(); + }); + + /*********************************** Ndk::Entity **********************************/ + entityClass.SetMethod("Enable", &Entity::Enable); + entityClass.SetMethod("GetId", &Entity::GetId); + entityClass.SetMethod("GetWorld", &Entity::GetWorld); + entityClass.SetMethod("Kill", &Entity::Kill); + entityClass.SetMethod("IsEnabled", &Entity::IsEnabled); + entityClass.SetMethod("IsValid", &Entity::IsValid); + entityClass.SetMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); + entityClass.SetMethod("RemoveAllComponents", &Entity::RemoveAllComponents); + entityClass.SetMethod("__tostring", &EntityHandle::ToString); + + entityClass.SetMethod("AddComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + { + int index = 1; + ComponentIndex componentIndex = lua.Check(&index); + + if (componentIndex > m_componentBinding.size()) + { + lua.Error("Invalid component index"); + return 0; + } + + ComponentBinding& binding = m_componentBinding[componentIndex]; + if (!binding.valid) + { + lua.Error("This component is not available to the LuaAPI"); + return 0; + } + + return binding.adder(lua, handle); + }); + + entityClass.SetMethod("GetComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + { + int index = 1; + ComponentIndex componentIndex = lua.Check(&index); + + if (!handle->HasComponent(componentIndex)) + { + lua.PushNil(); + return 1; + } + + if (componentIndex > m_componentBinding.size()) + { + lua.Error("Invalid component index"); + return 0; + } + + ComponentBinding& binding = m_componentBinding[componentIndex]; + if (!binding.valid) + { + lua.Error("This component is not available to the LuaAPI"); + return 0; + } + + return binding.getter(lua, handle->GetComponent(componentIndex)); + }); + + /*********************************** Ndk::World **********************************/ + worldClass.SetMethod("CreateEntity", &World::CreateEntity); + worldClass.SetMethod("CreateEntities", &World::CreateEntities); + worldClass.SetMethod("Clear", &World::Clear); + + + #ifndef NDK_SERVER + /*********************************** Ndk::GraphicsComponent **********************************/ + graphicsComponent.SetMethod("Attach", &GraphicsComponent::Attach, 0); + #endif + + + // Components functions + m_componentBinding.resize(BaseComponent::GetMaxComponentIndex() + 1); + + EnableComponentBinding(); + + #ifndef NDK_SERVER + EnableComponentBinding(); + #endif + } + + template + void LuaBinding::EnableComponentBinding() + { + ComponentBinding binding; + binding.adder = &AddComponentOfType; + binding.getter = &PushComponentOfType; + binding.valid = true; + + NazaraAssert(T::componentIndex < m_componentBinding.size(), "Component index is over component binding size"); + + m_componentBinding[T::componentIndex] = std::move(binding); + } + + void LuaBinding::RegisterSDK(Nz::LuaInstance& instance) + { + // Classes + entityClass.Register(instance); + nodeComponent.Register(instance); + worldClass.Register(instance); + + #ifndef NDK_SERVER + graphicsComponent.Register(instance); + #endif + + // Enums + + // ComponentType (fake enumeration to expose component indexes) + instance.PushTable(); + { + #ifndef NDK_SERVER + instance.PushInteger(GraphicsComponent::componentIndex); + instance.SetField("Graphics"); + #endif + + instance.PushInteger(NodeComponent::componentIndex); + instance.SetField("Node"); + } + instance.SetGlobal("ComponentType"); + } +} \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_SDK.cpp b/SDK/src/NDK/LuaBinding_Utility.cpp similarity index 56% rename from SDK/src/NDK/LuaAPI_SDK.cpp rename to SDK/src/NDK/LuaBinding_Utility.cpp index 50bd66005..65447a0b3 100644 --- a/SDK/src/NDK/LuaAPI_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_Utility.cpp @@ -1,94 +1,94 @@ -// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp - +#include #include -#include -#include -#include -#include -#include namespace Ndk { - namespace + void LuaBinding::BindUtility() { - int AddNilComponent(Nz::LuaInstance& lua, EntityHandle&) + /*********************************** Nz::AbstractImage **********************************/ + abstractImage.SetMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); + abstractImage.SetMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); + abstractImage.SetMethod("GetFormat", &Nz::AbstractImage::GetFormat); + abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); + abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); + abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); + abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); + abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); + abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); + abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); + abstractImage.SetMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); + + abstractImage.SetMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int { - lua.PushNil(); - return 1; - } - - template - int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle) - { - static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); - - T& component = handle->AddComponent(); - lua.Push(component.CreateHandle()); - return 1; - } - - int AddComponent(Nz::LuaInstance& lua, EntityHandle& handle, ComponentIndex index) - { - std::vector componentAdder(BaseComponent::GetMaxComponentIndex(), AddNilComponent); - componentAdder[GraphicsComponent::componentIndex] = &AddComponentOfType; - componentAdder[NodeComponent::componentIndex] = &AddComponentOfType; - - if (index > componentAdder.size()) + unsigned int argCount = std::min(lua.GetStackTop(), 1U); + switch (argCount) { - lua.Error("Invalid component index"); - return 0; + case 0: + return lua.Push(abstractImage->GetMemoryUsage()); + + case 1: + { + int index = 1; + Nz::UInt8 level(lua.Check(&index)); + + return lua.Push(abstractImage->GetMemoryUsage(level)); + } } - return componentAdder[index](lua, handle); - } + lua.Error("No matching overload for method GetMemoryUsage"); + return 0; + }); - int PushNilComponent(Nz::LuaInstance& lua, BaseComponent&) + abstractImage.SetMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int { - lua.PushNil(); - return 1; - } + unsigned int argCount = std::min(lua.GetStackTop(), 6U); + int argIndex = 1; - template - int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component) - { - static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + std::size_t bufferSize = 0; + const Nz::UInt8* pixels = reinterpret_cast(lua.CheckString(argIndex++, &bufferSize)); - T& rightComponent = static_cast(component); - lua.Push(rightComponent.CreateHandle()); - return 1; - } - - int PushComponent(Nz::LuaInstance& lua, BaseComponent& component) - { - std::vector componentConverter(BaseComponent::GetMaxComponentIndex(), PushNilComponent); - componentConverter[GraphicsComponent::componentIndex] = &PushComponentOfType; - componentConverter[NodeComponent::componentIndex] = &PushComponentOfType; - - ComponentIndex index = component.GetIndex(); - - if (index > componentConverter.size()) + if (argCount < 2 || lua.IsOfType(2, Nz::LuaType_Number)) { - lua.Error("Invalid component index"); - return 0; + // bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + unsigned int srcWidth = lua.Check(&argIndex, 0); + unsigned int srcHeight = lua.Check(&argIndex, 0); + Nz::UInt8 level = lua.Check(&argIndex, 0); + + ///TODO: Buffer checks (Nz::ByteBufferView ?) + return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); } + /* Disabled until Box and Rect have been ported + else if (lua.IsOfType(2, "Box")) + { + // bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + Nz::Boxui box = lua.Check(&argIndex); + unsigned int srcWidth = lua.Check(&argIndex, 0); + unsigned int srcHeight = lua.Check(&argIndex, 0); + Nz::UInt8 level = lua.Check(&argIndex, 0); - return componentConverter[index](lua, component); - } - } + ///TODO: Buffer checks (Nz::ByteBufferView ?) + return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); + } + else if (lua.IsOfType(2, "Rect")) + { + // bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) + Nz::Rectui box = lua.Check(&argIndex); + unsigned int srcWidth = lua.Check(&argIndex, 0); + unsigned int srcHeight = lua.Check(&argIndex, 0); + Nz::UInt8 level = lua.Check(&argIndex, 0); - void LuaAPI::Register_SDK(Nz::LuaInstance& instance) - { - Nz::LuaClass graphicsComponent("GraphicsComponent"); + ///TODO: Buffer checks (Nz::ByteBufferView ?) + return lua.Push(abstractImage->Update(pixels, srcWidth, srcHeight, level)); + }*/ - graphicsComponent.SetMethod("Attach", &GraphicsComponent::Attach, 0); - - graphicsComponent.Register(instance); - - Nz::LuaClass nodeClass("Node"); //< TODO: Move to Utility + lua.Error("No matching overload for method Update"); + return 0; + }); + /*********************************** Nz::Node **********************************/ nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); //nodeClass.SetMethod("GetChilds", &Nz::Node::GetChilds); nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); @@ -245,69 +245,11 @@ namespace Ndk lua.Error("No matching overload for method SetInitialScale"); return 0; }); + } + void LuaBinding::RegisterUtility(Nz::LuaInstance& instance) + { + abstractImage.Register(instance); nodeClass.Register(instance); - - Nz::LuaClass nodeComponent("NodeComponent"); - nodeComponent.Inherit(nodeClass, [] (NodeComponentHandle* handle) -> Nz::Node* - { - return handle->GetObject(); - }); - - nodeComponent.Register(instance); - - Nz::LuaClass entityClass("Entity"); - - entityClass.SetMethod("Enable", &Entity::Enable); - entityClass.SetMethod("GetId", &Entity::GetId); - entityClass.SetMethod("GetWorld", &Entity::GetWorld); - entityClass.SetMethod("Kill", &Entity::Kill); - entityClass.SetMethod("IsEnabled", &Entity::IsEnabled); - entityClass.SetMethod("IsValid", &Entity::IsValid); - entityClass.SetMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); - entityClass.SetMethod("RemoveAllComponents", &Entity::RemoveAllComponents); - entityClass.SetMethod("__tostring", &EntityHandle::ToString); - - entityClass.SetMethod("AddComponent", [] (Nz::LuaInstance& lua, EntityHandle& handle) -> int - { - int index = 1; - ComponentIndex componentIndex = lua.Check(&index); - - return AddComponent(lua, handle, componentIndex); - }); - - entityClass.SetMethod("GetComponent", [] (Nz::LuaInstance& lua, EntityHandle& handle) -> int - { - int index = 1; - ComponentIndex componentIndex = lua.Check(&index); - - if (!handle->HasComponent(componentIndex)) - { - lua.PushNil(); - return 1; - } - - return PushComponent(lua, handle->GetComponent(componentIndex)); - }); - - entityClass.Register(instance); - - Nz::LuaClass worldClass("World"); - - worldClass.SetMethod("CreateEntity", &World::CreateEntity); - worldClass.SetMethod("CreateEntities", &World::CreateEntities); - worldClass.SetMethod("Clear", &World::Clear); - - worldClass.Register(instance); - - instance.PushTable(0, 2); - { - instance.PushInteger(GraphicsComponent::componentIndex); - instance.SetField("Graphics"); - - instance.PushInteger(NodeComponent::componentIndex); - instance.SetField("Node"); - } - instance.SetGlobal("ComponentType"); } } \ No newline at end of file diff --git a/build/scripts/tools/ndk.lua b/build/scripts/tools/ndk.lua index ae0c99881..33c79c3fb 100644 --- a/build/scripts/tools/ndk.lua +++ b/build/scripts/tools/ndk.lua @@ -8,7 +8,8 @@ TOOL.Defines = { } TOOL.Includes = { - "../SDK/include" + "../SDK/include", + "../SDK/src" } TOOL.Files = { diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index 1f8102a41..6b6d32941 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -9,7 +9,8 @@ TOOL.Defines = { } TOOL.Includes = { - "../SDK/include" + "../SDK/include", + "../SDK/src" } TOOL.Files = { @@ -29,9 +30,9 @@ TOOL.FilesExclusion = { "../SDK/**/ListenerComponent.*", "../SDK/**/ListenerSystem.*", "../SDK/**/RenderSystem.*", - "../SDK/**/LuaAPI_Audio.*", - "../SDK/**/LuaAPI_Graphics.*", - "../SDK/**/LuaAPI_Renderer.*", + "../SDK/**/LuaBinding_Audio.*", + "../SDK/**/LuaBinding_Graphics.*", + "../SDK/**/LuaBinding_Renderer.*" } TOOL.Libraries = { From e447b6c928f110a11a7726a7663b1f0468f22908 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:55:17 +0200 Subject: [PATCH 193/229] Lua/LuaInstance: Fix defaulting floating point Former-commit-id: 2e12b456c7e998253d58100948c9b069a00abca4 --- include/Nazara/Lua/LuaInstance.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 685c50719..a445df491 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -88,7 +88,7 @@ namespace Nz } template - std::enable_if_t::value && !std::is_enum::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) + std::enable_if_t::value && !std::is_enum::value && !std::is_floating_point::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { if (instance.IsValid(index)) return LuaImplQueryArg(instance, index, arg, tag); From 916e3c2d7c83beea1e7a16b15ed0e13171e09a04 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:55:43 +0200 Subject: [PATCH 194/229] Sdk/LuaAPI: Add querying color Former-commit-id: 946071a4642f0b649f26655d5195894057debfbc --- SDK/include/NDK/LuaAPI.inl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 5b78a7e21..703b295c3 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include #include #include @@ -19,6 +20,18 @@ namespace Nz { + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Color* color, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + color->r = instance.CheckField("r", index); + color->g = instance.CheckField("g", index); + color->b = instance.CheckField("b", index); + color->a = instance.CheckField("a", 255, index); + + return 1; + } + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag) { switch (instance.GetType(index)) From 1dd13046cdc815d766d612e072d9ccdd5ec682f1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:55:59 +0200 Subject: [PATCH 195/229] Sdk/LuaAPI: Add Vector2 Former-commit-id: d5f7b8cf7baa7d08562214008155467b9fa888ed --- SDK/include/NDK/LuaAPI.inl | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 703b295c3..7380e38e3 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -151,11 +151,11 @@ namespace Nz if (index < 0 && index > -3) instance.Error("Vector3 expected, three numbers are required to convert it"); - vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1), instance.CheckNumber(index + 2)); + vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1), instance.CheckNumber(index + 2, 0.0)); return 3; case Nz::LuaType_Table: - vec->Set(instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", index)); + vec->Set(instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", 0.0, index)); return 1; default: @@ -273,6 +273,24 @@ namespace Nz return 1; } + inline int LuaImplReplyVal(const LuaInstance& instance, Vector2d val, TypeTag) + { + instance.PushInstance("Vector2", val); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Vector2f val, TypeTag) + { + instance.PushInstance("Vector2", val); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Vector2ui val, TypeTag) + { + instance.PushInstance("Vector2", val); + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d val, TypeTag) { instance.PushInstance("Vector3", val); From 9a472a4a1c78507141d1ddd04eeb71ed21c58824 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:56:57 +0200 Subject: [PATCH 196/229] Sdk/LuaAPI: Bind console Former-commit-id: 70738fdc709b867bead746a0091dcb50a5ca67ea --- SDK/include/NDK/LuaAPI.inl | 20 ++++++++++++++++++++ SDK/src/NDK/LuaBinding.cpp | 1 + SDK/src/NDK/LuaBinding.hpp | 1 + SDK/src/NDK/LuaBinding_SDK.cpp | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 7380e38e3..d11c3982e 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #ifndef NDK_SERVER #include #include +#include #endif namespace Nz @@ -315,6 +317,12 @@ namespace Nz return 1; } + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Application* ptr, TypeTag) + { + instance.PushInstance("Application", ptr); + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle handle, TypeTag) { instance.PushInstance("Entity", handle); @@ -327,6 +335,12 @@ namespace Nz return 1; } + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::VelocityComponentHandle handle, TypeTag) + { + instance.PushInstance("VelocityComponent", handle); + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag) { instance.PushInstance("World", ptr); @@ -340,6 +354,12 @@ namespace Nz } #ifndef NDK_SERVER + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::ConsoleHandle handle, TypeTag) + { + instance.PushInstance("Console", handle); + return 1; + } + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle handle, TypeTag) { instance.PushInstance("GraphicsComponent", handle); diff --git a/SDK/src/NDK/LuaBinding.cpp b/SDK/src/NDK/LuaBinding.cpp index 0c2766ca7..9af6aab40 100644 --- a/SDK/src/NDK/LuaBinding.cpp +++ b/SDK/src/NDK/LuaBinding.cpp @@ -43,6 +43,7 @@ namespace Ndk modelClass("Model"), // SDK + consoleClass("Console"), graphicsComponent("GraphicsComponent") #endif { diff --git a/SDK/src/NDK/LuaBinding.hpp b/SDK/src/NDK/LuaBinding.hpp index c8dda3c2f..2bb01421f 100644 --- a/SDK/src/NDK/LuaBinding.hpp +++ b/SDK/src/NDK/LuaBinding.hpp @@ -106,6 +106,7 @@ namespace Ndk Nz::LuaClass modelClass; // SDK + Nz::LuaClass consoleClass; Nz::LuaClass graphicsComponent; #endif }; diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index bb8ec3475..15e81b63b 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -44,12 +44,34 @@ namespace Ndk void LuaBinding::BindSDK() { - /*********************************** Ndk::NodeComponent **********************************/ - nodeComponent.Inherit(nodeClass, [] (NodeComponentHandle* handle) -> Nz::Node* + + /*********************************** Ndk::Console **********************************/ + consoleClass.Inherit(nodeClass, [] (ConsoleHandle* handle) -> Nz::Node* { return handle->GetObject(); }); + consoleClass.SetMethod("AddLine", &Console::AddLine, Nz::Color::White); + consoleClass.SetMethod("Clear", &Console::Clear); + consoleClass.SetMethod("GetCharacterSize", &Console::GetCharacterSize); + consoleClass.SetMethod("GetHistory", &Console::GetHistory); + consoleClass.SetMethod("GetHistoryBackground", &Console::GetHistoryBackground); + consoleClass.SetMethod("GetInput", &Console::GetInput); + consoleClass.SetMethod("GetInputBackground", &Console::GetInputBackground); + consoleClass.SetMethod("GetSize", &Console::GetSize); + //consoleClass.SetMethod("GetTextFont", &Console::GetTextFont); + + consoleClass.SetMethod("IsVisible", &Console::IsVisible); + + consoleClass.SetMethod("SendCharacter", &Console::SendCharacter); + //consoleClass.SetMethod("SendEvent", &Console::SendEvent); + + consoleClass.SetMethod("SetCharacterSize", &Console::SetCharacterSize); + consoleClass.SetMethod("SetSize", &Console::SetSize); + //consoleClass.SetMethod("SetTextFont", &Console::SetTextFont); + + consoleClass.SetMethod("Show", &Console::Show, true); + /*********************************** Ndk::Entity **********************************/ entityClass.SetMethod("Enable", &Entity::Enable); entityClass.SetMethod("GetId", &Entity::GetId); @@ -109,6 +131,12 @@ namespace Ndk return binding.getter(lua, handle->GetComponent(componentIndex)); }); + /*********************************** Ndk::NodeComponent **********************************/ + nodeComponent.Inherit(nodeClass, [] (NodeComponentHandle* handle) -> Nz::Node* + { + return handle->GetObject(); + }); + /*********************************** Ndk::World **********************************/ worldClass.SetMethod("CreateEntity", &World::CreateEntity); worldClass.SetMethod("CreateEntities", &World::CreateEntities); @@ -152,6 +180,7 @@ namespace Ndk worldClass.Register(instance); #ifndef NDK_SERVER + consoleClass.Register(instance); graphicsComponent.Register(instance); #endif From 8732cc94595fa19e3a42ef2a0db384565cf9e60b Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:57:07 +0200 Subject: [PATCH 197/229] Sdk/Console: Add Clear method Former-commit-id: 6230bf71538d3436cd1c247e9645e54fff0e0a2d --- SDK/include/NDK/Console.hpp | 9 ++++++++- SDK/src/NDK/Console.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 0f6c08d43..78caac3f2 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -7,6 +7,8 @@ #ifndef NDK_CONSOLE_HPP #define NDK_CONSOLE_HPP +#include +#include #include #include #include @@ -21,9 +23,12 @@ namespace Nz namespace Ndk { + class Console; class Entity; - class NDK_API Console : public Nz::Node + using ConsoleHandle = Nz::ObjectHandle; + + class NDK_API Console : public Nz::Node, public Nz::HandledObject { public: Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance); @@ -33,6 +38,8 @@ namespace Ndk void AddLine(const Nz::String& text, const Nz::Color& color = Nz::Color::White); + void Clear(); + inline unsigned int GetCharacterSize() const; inline const EntityHandle& GetHistory() const; inline const EntityHandle& GetHistoryBackground() const; diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 976bb7fd1..ae6461b83 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -92,6 +92,12 @@ namespace Ndk RefreshHistory(); } + void Console::Clear() + { + m_historyLines.clear(); + RefreshHistory(); + } + void Console::SendCharacter(char32_t character) { switch (character) From 2736081578d0b3274f4090e86ae5b70b5a82886f Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:57:23 +0200 Subject: [PATCH 198/229] Sdk/Application: Add GetUpdateTime() Former-commit-id: 55acb0529b41860c56ad0717ab15005e4d237f0f --- SDK/include/NDK/Application.hpp | 4 ++++ SDK/include/NDK/Application.inl | 5 +++++ SDK/src/NDK/Application.cpp | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index 644dcc971..91c1bc5da 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -20,6 +20,7 @@ namespace Ndk public: inline Application(); Application(const Application&) = delete; + Application(Application&&) = delete; inline ~Application(); #ifndef NDK_SERVER @@ -27,11 +28,14 @@ namespace Ndk #endif template World& AddWorld(Args&&... args); + inline float GetUpdateTime() const; + bool Run(); inline void Quit(); Application& operator=(const Application&) = delete; + Application& operator=(Application&&) = delete; inline static Application* Instance(); diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index ca1fa1ffb..e65d8d5d0 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -54,6 +54,11 @@ namespace Ndk return m_worlds.back(); } + inline float Application::GetUpdateTime() const + { + return m_updateTime; + } + inline void Application::Quit() { m_shouldQuit = true; diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index e15ba2f92..8024614e6 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -28,11 +28,11 @@ namespace Ndk } #endif - float elapsedTime = m_updateClock.GetSeconds(); + m_updateTime = m_updateClock.GetSeconds(); m_updateClock.Restart(); for (World& world : m_worlds) - world.Update(elapsedTime); + world.Update(m_updateTime); if (m_shouldQuit) return false; From fdccc9e51037e2d188ed27bcf18d86ab1991eaf1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:57:51 +0200 Subject: [PATCH 199/229] Sdk/LuaAPI: Bind VelocityComponent Former-commit-id: 7e51aa57854b58cdf8b243f1e02e7bb90a943709 --- .../NDK/Components/VelocityComponent.hpp | 5 ++- SDK/src/NDK/LuaBinding.cpp | 1 + SDK/src/NDK/LuaBinding.hpp | 2 ++ SDK/src/NDK/LuaBinding_SDK.cpp | 35 +++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/Components/VelocityComponent.hpp b/SDK/include/NDK/Components/VelocityComponent.hpp index 28d317a2c..33d97b030 100644 --- a/SDK/include/NDK/Components/VelocityComponent.hpp +++ b/SDK/include/NDK/Components/VelocityComponent.hpp @@ -13,8 +13,11 @@ namespace Ndk { class Entity; + class VelocityComponent; - class NDK_API VelocityComponent : public Component + using VelocityComponentHandle = Nz::ObjectHandle; + + class NDK_API VelocityComponent : public Component, public Nz::HandledObject { public: VelocityComponent(const Nz::Vector3f& velocity = Nz::Vector3f::Zero()); diff --git a/SDK/src/NDK/LuaBinding.cpp b/SDK/src/NDK/LuaBinding.cpp index 9af6aab40..0936ac9aa 100644 --- a/SDK/src/NDK/LuaBinding.cpp +++ b/SDK/src/NDK/LuaBinding.cpp @@ -28,6 +28,7 @@ namespace Ndk // SDK nodeComponent("NodeComponent"), entityClass("Entity"), + velocityComponent("VelocityComponent"), worldClass("World") #ifndef NDK_SERVER diff --git a/SDK/src/NDK/LuaBinding.hpp b/SDK/src/NDK/LuaBinding.hpp index 2bb01421f..184996991 100644 --- a/SDK/src/NDK/LuaBinding.hpp +++ b/SDK/src/NDK/LuaBinding.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #endif namespace Ndk @@ -81,6 +82,7 @@ namespace Ndk // SDK Nz::LuaClass entityClass; Nz::LuaClass nodeComponent; + Nz::LuaClass velocityComponent; Nz::LuaClass worldClass; using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index 15e81b63b..ebbc236ce 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -137,6 +137,36 @@ namespace Ndk return handle->GetObject(); }); + /*********************************** Ndk::VelocityComponent **********************************/ + velocityComponent.SetGetter([] (Nz::LuaInstance& lua, VelocityComponentHandle& instance) + { + std::size_t length; + const char* member = lua.CheckString(1, &length); + + if (std::strcmp(member, "Linear") == 0) + { + lua.Push(instance->linearVelocity); + return true; + } + + return false; + }); + + velocityComponent.SetSetter([] (Nz::LuaInstance& lua, VelocityComponentHandle& instance) + { + std::size_t length; + const char* member = lua.CheckString(1, &length); + + int argIndex = 2; + if (std::strcmp(member, "Linear") == 0) + { + instance->linearVelocity = lua.Check(&argIndex); + return true; + } + + return false; + }); + /*********************************** Ndk::World **********************************/ worldClass.SetMethod("CreateEntity", &World::CreateEntity); worldClass.SetMethod("CreateEntities", &World::CreateEntities); @@ -153,6 +183,7 @@ namespace Ndk m_componentBinding.resize(BaseComponent::GetMaxComponentIndex() + 1); EnableComponentBinding(); + EnableComponentBinding(); #ifndef NDK_SERVER EnableComponentBinding(); @@ -177,6 +208,7 @@ namespace Ndk // Classes entityClass.Register(instance); nodeComponent.Register(instance); + velocityComponent.Register(instance); worldClass.Register(instance); #ifndef NDK_SERVER @@ -196,6 +228,9 @@ namespace Ndk instance.PushInteger(NodeComponent::componentIndex); instance.SetField("Node"); + + instance.PushInteger(VelocityComponent::componentIndex); + instance.SetField("Velocity"); } instance.SetGlobal("ComponentType"); } From 6669733af37046ea0f95b58386cd4d138e10517b Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:58:02 +0200 Subject: [PATCH 200/229] Sdk/LuaAPI: Fix audio binding Former-commit-id: 09149563e8f755092f91786bc31dcaea0638f3cb --- SDK/src/NDK/LuaBinding_Audio.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/SDK/src/NDK/LuaBinding_Audio.cpp b/SDK/src/NDK/LuaBinding_Audio.cpp index a894595b3..b10aa6206 100644 --- a/SDK/src/NDK/LuaBinding_Audio.cpp +++ b/SDK/src/NDK/LuaBinding_Audio.cpp @@ -63,8 +63,6 @@ namespace Ndk }); /*********************************** Nz::SoundEmitter **********************************/ - Nz::LuaClass soundEmitter("SoundEmitter"); - soundEmitter.SetMethod("EnableLooping", &Nz::SoundEmitter::EnableLooping); soundEmitter.SetMethod("EnableSpatialization", &Nz::SoundEmitter::EnableSpatialization); soundEmitter.SetMethod("GetAttenuation", &Nz::SoundEmitter::GetAttenuation); @@ -89,7 +87,6 @@ namespace Ndk soundEmitter.SetMethod("Stop", &Nz::SoundEmitter::Stop); /*********************************** Nz::Sound **********************************/ - Nz::LuaClass soundClass("Sound"); soundClass.Inherit(soundEmitter); soundClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Sound* From 50f25e6bccbc305d9112875f1c8172dc1df37e76 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:58:22 +0200 Subject: [PATCH 201/229] Sdk/LuaAPI: Add Application binding Former-commit-id: fd926aaaf6a8df85c93a2ceae14db7bc49516759 --- SDK/src/NDK/LuaBinding.cpp | 1 + SDK/src/NDK/LuaBinding.hpp | 2 ++ SDK/src/NDK/LuaBinding_SDK.cpp | 14 ++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/SDK/src/NDK/LuaBinding.cpp b/SDK/src/NDK/LuaBinding.cpp index 0936ac9aa..ffbbf27c3 100644 --- a/SDK/src/NDK/LuaBinding.cpp +++ b/SDK/src/NDK/LuaBinding.cpp @@ -26,6 +26,7 @@ namespace Ndk nodeClass("Node"), // SDK + application("Application"), nodeComponent("NodeComponent"), entityClass("Entity"), velocityComponent("VelocityComponent"), diff --git a/SDK/src/NDK/LuaBinding.hpp b/SDK/src/NDK/LuaBinding.hpp index 184996991..c1803a201 100644 --- a/SDK/src/NDK/LuaBinding.hpp +++ b/SDK/src/NDK/LuaBinding.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,7 @@ namespace Ndk Nz::LuaClass nodeClass; // SDK + Nz::LuaClass application; Nz::LuaClass entityClass; Nz::LuaClass nodeComponent; Nz::LuaClass velocityComponent; diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index ebbc236ce..ec041e4b2 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -44,6 +44,19 @@ namespace Ndk void LuaBinding::BindSDK() { + /*********************************** Ndk::Application **********************************/ + + #ifndef NDK_SERVER + //application.SetMethod("AddWindow", &Application::AddWindow); + #endif + application.SetMethod("AddWorld", [] (Nz::LuaInstance& instance, Application* application) -> int + { + instance.Push(application->AddWorld().CreateHandle()); + return 1; + }); + + application.SetMethod("GetUpdateTime", &Application::GetUpdateTime); + application.SetMethod("Quit", &Application::Quit); /*********************************** Ndk::Console **********************************/ consoleClass.Inherit(nodeClass, [] (ConsoleHandle* handle) -> Nz::Node* @@ -206,6 +219,7 @@ namespace Ndk void LuaBinding::RegisterSDK(Nz::LuaInstance& instance) { // Classes + application.Register(instance); entityClass.Register(instance); nodeComponent.Register(instance); velocityComponent.Register(instance); From 3e7facc3421a36d276d0a20e32a4837fd3cc59a9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:58:37 +0200 Subject: [PATCH 202/229] Sdk/World: Fix handles when moving Former-commit-id: 0e5866864150bd607db028deb9c972ace6b50caf --- SDK/include/NDK/World.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index 64212357a..91ebc3922 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -13,7 +13,8 @@ namespace Ndk AddDefaultSystems(); } - inline World::World(World&& world) noexcept + inline World::World(World&& world) noexcept : + HandledObject(std::move(world)) { operator=(std::move(world)); } From 0a17aacae6d5fcde7f7be6960e60b3378433ffb9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:58:45 +0200 Subject: [PATCH 203/229] Sdk: Fix server building Former-commit-id: 1c3e0626fcaacbb414c526862a5608c36325f464 --- SDK/include/NDK/Components.hpp | 11 +++++++---- SDK/include/NDK/Systems.hpp | 7 +++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/SDK/include/NDK/Components.hpp b/SDK/include/NDK/Components.hpp index a6d41e543..46392ab7c 100644 --- a/SDK/include/NDK/Components.hpp +++ b/SDK/include/NDK/Components.hpp @@ -5,13 +5,16 @@ #ifndef NDK_COMPONENTS_GLOBAL_HPP #define NDK_COMPONENTS_GLOBAL_HPP -#include #include -#include -#include -#include #include #include #include +#ifndef NDK_SERVER +#include +#include +#include +#include +#endif + #endif // NDK_COMPONENTS_GLOBAL_HPP diff --git a/SDK/include/NDK/Systems.hpp b/SDK/include/NDK/Systems.hpp index d9bd12c75..193438b5e 100644 --- a/SDK/include/NDK/Systems.hpp +++ b/SDK/include/NDK/Systems.hpp @@ -5,9 +5,12 @@ #ifndef NDK_SYSTEMS_GLOBAL_HPP #define NDK_SYSTEMS_GLOBAL_HPP -#include #include -#include #include +#ifndef NDK_SERVER +#include +#include +#endif + #endif // NDK_SYSTEMS_GLOBAL_HPP From d8610d139b83a96698b6dab01a6dc1316c53996d Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 18:58:58 +0200 Subject: [PATCH 204/229] Utility/STBSaver: Fix failure error message Former-commit-id: 5985737a6e1690e66c8e1a2c6a4edb2c74aebdb0 --- src/Nazara/Utility/Formats/STBSaver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Formats/STBSaver.cpp b/src/Nazara/Utility/Formats/STBSaver.cpp index e68210d93..4166de86f 100644 --- a/src/Nazara/Utility/Formats/STBSaver.cpp +++ b/src/Nazara/Utility/Formats/STBSaver.cpp @@ -173,7 +173,7 @@ namespace Nz if (!stbi_write_hdr_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, reinterpret_cast(tempImage.GetConstPixels()))) { - NazaraError("Failed to write BMP to stream"); + NazaraError("Failed to write HDR to stream"); return false; } @@ -193,7 +193,7 @@ namespace Nz if (!stbi_write_png_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels(), 0)) { - NazaraError("Failed to write BMP to stream"); + NazaraError("Failed to write PNG to stream"); return false; } @@ -213,7 +213,7 @@ namespace Nz if (!stbi_write_tga_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels())) { - NazaraError("Failed to write BMP to stream"); + NazaraError("Failed to write TGA to stream"); return false; } From 812e7a940c4a4091f71a8eac4bacc9b64e5f286d Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 22:25:30 +0200 Subject: [PATCH 205/229] Sdk/Application: Fix world updating once after window closing Former-commit-id: f02603702c2e1e79fc71d95739adeedec0347457 --- SDK/src/NDK/Application.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 8024614e6..df2dfa12c 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -28,20 +28,20 @@ namespace Ndk } #endif + #ifndef NDK_SERVER + if (m_exitOnClosedWindows && !hasAtLeastOneActiveWindow) + return false; + #endif + + if (m_shouldQuit) + return false; + m_updateTime = m_updateClock.GetSeconds(); m_updateClock.Restart(); for (World& world : m_worlds) world.Update(m_updateTime); - if (m_shouldQuit) - return false; - - #ifndef NDK_SERVER - if (m_exitOnClosedWindows && !hasAtLeastOneActiveWindow) - return false; - #endif - return true; } From 621e0d123c1fe4dedf7eb0d28b5831020c3ff89c Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Apr 2016 22:25:59 +0200 Subject: [PATCH 206/229] Sdk/Console: Fix SetCharacterSize not changing size of history and input Former-commit-id: 1aed585ee4d4f0e5eb16edc1a50467893b4e7ede --- SDK/src/NDK/Console.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index ae6461b83..31586d346 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -168,6 +168,12 @@ namespace Ndk void Console::SetCharacterSize(unsigned int size) { m_characterSize = size; + + m_historyDrawer.SetCharacterSize(m_characterSize); + m_historyTextSprite->Update(m_historyDrawer); + m_inputDrawer.SetCharacterSize(m_characterSize); + m_inputTextSprite->Update(m_inputDrawer); + Layout(); } From de8f8e074344a9cca1486e0eb8f183d6984ef47b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 Apr 2016 18:55:55 +0200 Subject: [PATCH 207/229] Audio/Music: Fix infinite loop Former-commit-id: 027a5c19500c774e13ed51f47b16e754dfb44721 --- src/Nazara/Audio/Music.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 8ff8e2a7f..be13419dc 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -262,17 +262,22 @@ namespace Nz unsigned int sampleCount = m_impl->chunkSamples.size(); unsigned int sampleRead = 0; - // Lecture depuis le stream pour remplir le buffer + // Fill the buffer by reading from the stream for (;;) { sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount - sampleRead); - if (sampleRead < sampleCount && !m_impl->loop) - break; // Fin du stream (On ne boucle pas) + if (sampleRead < sampleCount && m_impl->loop) + { + // In case we read less than expected, assume we reached the end of the stream and seek back to the beginning + m_impl->stream->Seek(0); + continue; + } - m_impl->stream->Seek(0); // On boucle au début du stream et on remplit à nouveau + // Either we read the size we wanted, either we're not looping + break; } - // Mise à jour du buffer (envoi à OpenAL) et placement dans la file d'attente + // Update the buffer (send it to OpenAL) and queue it if we got any data if (sampleRead > 0) { alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(Int16), m_impl->sampleRate); From f8a716aa84b883f1376db1365ddf616295d84147 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 Apr 2016 18:56:16 +0200 Subject: [PATCH 208/229] Sdk/LuaAPI: Bind class music Former-commit-id: 713c12b5a6e64debff2a6822d1aacece0d9e76cb --- SDK/src/NDK/LuaBinding.cpp | 1 + SDK/src/NDK/LuaBinding.hpp | 1 + SDK/src/NDK/LuaBinding_Audio.cpp | 107 +++++++++++++++++++++++-------- 3 files changed, 82 insertions(+), 27 deletions(-) diff --git a/SDK/src/NDK/LuaBinding.cpp b/SDK/src/NDK/LuaBinding.cpp index ffbbf27c3..ab99eb101 100644 --- a/SDK/src/NDK/LuaBinding.cpp +++ b/SDK/src/NDK/LuaBinding.cpp @@ -36,6 +36,7 @@ namespace Ndk , // Audio + musicClass("Music"), soundBuffer("SoundBuffer"), soundEmitter("SoundEmitter"), soundClass("Sound"), diff --git a/SDK/src/NDK/LuaBinding.hpp b/SDK/src/NDK/LuaBinding.hpp index c1803a201..93363f7fb 100644 --- a/SDK/src/NDK/LuaBinding.hpp +++ b/SDK/src/NDK/LuaBinding.hpp @@ -101,6 +101,7 @@ namespace Ndk #ifndef NDK_SERVER // Audio + Nz::LuaClass musicClass; Nz::LuaClass soundClass; Nz::LuaClass soundBuffer; Nz::LuaClass soundEmitter; diff --git a/SDK/src/NDK/LuaBinding_Audio.cpp b/SDK/src/NDK/LuaBinding_Audio.cpp index b10aa6206..542c6b716 100644 --- a/SDK/src/NDK/LuaBinding_Audio.cpp +++ b/SDK/src/NDK/LuaBinding_Audio.cpp @@ -7,6 +7,77 @@ namespace Ndk { void LuaBinding::BindAudio() { + /*********************************** Nz::Music **********************************/ + musicClass.Inherit(soundEmitter); + + musicClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Music* + { + return new Nz::Music; + }); + + //musicClass.SetMethod("Create", &Nz::Music::Create); + //musicClass.SetMethod("Destroy", &Nz::Music::Destroy); + + musicClass.SetMethod("EnableLooping", &Nz::Music::EnableLooping); + + musicClass.SetMethod("GetDuration", &Nz::Music::GetDuration); + musicClass.SetMethod("GetFormat", &Nz::Music::GetFormat); + musicClass.SetMethod("GetPlayingOffset", &Nz::Music::GetPlayingOffset); + musicClass.SetMethod("GetSampleCount", &Nz::Music::GetSampleCount); + musicClass.SetMethod("GetSampleRate", &Nz::Music::GetSampleRate); + musicClass.SetMethod("GetStatus", &Nz::Music::GetStatus); + + musicClass.SetMethod("IsLooping", &Nz::Music::IsLooping); + + musicClass.SetMethod("OpenFromFile", &Nz::Music::OpenFromFile, Nz::MusicParams()); + + musicClass.SetMethod("Pause", &Nz::Music::Pause); + musicClass.SetMethod("Play", &Nz::Music::Play); + + musicClass.SetMethod("SetPlayingOffset", &Nz::Music::SetPlayingOffset); + + musicClass.SetMethod("Stop", &Nz::Music::Stop); + + // Manual + musicClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Music& music) -> int + { + Nz::StringStream stream("Music("); + stream << music.GetFilePath() << ')'; + + lua.PushString(stream); + return 1; + }); + + /*********************************** Nz::Sound **********************************/ + soundClass.Inherit(soundEmitter); + + soundClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Sound* + { + return new Nz::Sound; + }); + + soundClass.SetMethod("GetBuffer", &Nz::Sound::GetBuffer); + + soundClass.SetMethod("IsPlayable", &Nz::Sound::IsPlayable); + soundClass.SetMethod("IsPlaying", &Nz::Sound::IsPlaying); + + soundClass.SetMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); + + soundClass.SetMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); + + // Manual + soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int + { + Nz::StringStream stream("Sound("); + if (const Nz::SoundBuffer* buffer = sound.GetBuffer()) + stream << buffer; + + stream << ')'; + + lua.PushString(stream); + return 1; + }); + /*********************************** Nz::SoundBuffer **********************************/ soundBuffer.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::SoundBufferRef* { @@ -14,11 +85,14 @@ namespace Ndk }); soundBuffer.SetMethod("Destroy", &Nz::SoundBuffer::Destroy); + soundBuffer.SetMethod("GetDuration", &Nz::SoundBuffer::GetDuration); soundBuffer.SetMethod("GetFormat", &Nz::SoundBuffer::GetFormat); soundBuffer.SetMethod("GetSampleCount", &Nz::SoundBuffer::GetSampleCount); soundBuffer.SetMethod("GetSampleRate", &Nz::SoundBuffer::GetSampleRate); + soundBuffer.SetMethod("IsValid", &Nz::SoundBuffer::IsValid); + soundBuffer.SetMethod("LoadFromFile", &Nz::SoundBuffer::LoadFromFile, Nz::SoundBufferParams()); soundBuffer.SetStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported); @@ -65,6 +139,7 @@ namespace Ndk /*********************************** Nz::SoundEmitter **********************************/ soundEmitter.SetMethod("EnableLooping", &Nz::SoundEmitter::EnableLooping); soundEmitter.SetMethod("EnableSpatialization", &Nz::SoundEmitter::EnableSpatialization); + soundEmitter.SetMethod("GetAttenuation", &Nz::SoundEmitter::GetAttenuation); soundEmitter.SetMethod("GetDuration", &Nz::SoundEmitter::GetDuration); soundEmitter.SetMethod("GetMinDistance", &Nz::SoundEmitter::GetMinDistance); @@ -74,48 +149,26 @@ namespace Ndk soundEmitter.SetMethod("GetStatus", &Nz::SoundEmitter::GetStatus); soundEmitter.SetMethod("GetVelocity", &Nz::Sound::GetVelocity); soundEmitter.SetMethod("GetVolume", &Nz::SoundEmitter::GetVolume); + soundEmitter.SetMethod("IsLooping", &Nz::SoundEmitter::IsLooping); soundEmitter.SetMethod("IsSpatialized", &Nz::SoundEmitter::IsSpatialized); + soundEmitter.SetMethod("Pause", &Nz::SoundEmitter::Pause); soundEmitter.SetMethod("Play", &Nz::SoundEmitter::Play); + soundEmitter.SetMethod("SetAttenuation", &Nz::SoundEmitter::SetAttenuation); soundEmitter.SetMethod("SetMinDistance", &Nz::SoundEmitter::SetMinDistance); soundEmitter.SetMethod("SetPitch", &Nz::SoundEmitter::SetPitch); soundEmitter.SetMethod("SetPosition", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetPosition); soundEmitter.SetMethod("SetVelocity", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetVelocity); soundEmitter.SetMethod("SetVolume", &Nz::SoundEmitter::SetVolume); + soundEmitter.SetMethod("Stop", &Nz::SoundEmitter::Stop); - - /*********************************** Nz::Sound **********************************/ - soundClass.Inherit(soundEmitter); - - soundClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Sound* - { - return new Nz::Sound; - }); - - soundClass.SetMethod("GetBuffer", &Nz::Sound::GetBuffer); - soundClass.SetMethod("IsPlayable", &Nz::Sound::IsPlayable); - soundClass.SetMethod("IsPlaying", &Nz::Sound::IsPlaying); - soundClass.SetMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); - soundClass.SetMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); - - // Manual - soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int - { - Nz::StringStream stream("Sound("); - if (const Nz::SoundBuffer* buffer = sound.GetBuffer()) - stream << buffer; - - stream << ')'; - - lua.PushString(stream); - return 1; - }); } void LuaBinding::RegisterAudio(Nz::LuaInstance& instance) { + musicClass.Register(instance); soundClass.Register(instance); soundBuffer.Register(instance); soundEmitter.Register(instance); From 8481a3ae901c775eb97d6a44857b870ea4750118 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 Apr 2016 22:41:47 +0200 Subject: [PATCH 209/229] Sdk/LuaAPI: Add MusicParams binding Former-commit-id: 430bfb2afc6c05d0dbc78788130460de8e578242 --- SDK/include/NDK/LuaAPI.inl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index d11c3982e..f4d780386 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -15,6 +15,7 @@ #include #ifndef NDK_SERVER +#include #include #include #include @@ -233,6 +234,15 @@ namespace Nz return 1; } + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MusicParams* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->forceMono = instance.CheckField("ForceMono", params->forceMono); + + return 1; + } + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag) { instance.CheckType(index, Nz::LuaType_Table); From 85c2cd43e7c0a9f5d748d73a776c98615cd7a2fb Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 Apr 2016 22:42:31 +0200 Subject: [PATCH 210/229] Sdk/Application: Store worlds in a list to prevent their memory position to move Former-commit-id: 918ce261e7b8faded4ad6bded48fc09a885ceb8c --- SDK/include/NDK/Application.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index 91c1bc5da..ef697e48a 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -43,7 +43,7 @@ namespace Ndk #ifndef NDK_SERVER std::vector> m_windows; #endif - std::vector m_worlds; + std::list m_worlds; Nz::Clock m_updateClock; #ifndef NDK_SERVER bool m_exitOnClosedWindows; From 265e1c0fbd67d316fde6f2c798d2a4c5b0ebed9d Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 4 Apr 2016 10:17:05 +0200 Subject: [PATCH 211/229] Fix compilation for gcc/clang + tests for serialization Former-commit-id: db9c93a1db3c57f268fc17e411402e071fc8675a --- SDK/include/NDK/Application.hpp | 1 + SDK/include/NDK/Application.inl | 2 + SDK/include/NDK/BaseComponent.inl | 2 +- SDK/src/NDK/LuaBinding_SDK.cpp | 4 +- SDK/src/NDK/World.cpp | 2 +- examples/Mario/main.cpp | 447 +++++++++++++++++++ include/Nazara/Audio/OpenAL.hpp | 3 +- include/Nazara/Core/ResourceSaver.hpp | 1 + include/Nazara/Core/ResourceSaver.inl | 2 +- include/Nazara/Graphics/SkyboxBackground.hpp | 2 +- include/Nazara/Math/BoundingVolume.inl | 2 +- include/Nazara/Math/Frustum.hpp | 8 +- include/Nazara/Math/Frustum.inl | 12 +- include/Nazara/Network/RUdpConnection.hpp | 8 +- include/Nazara/Renderer/OpenGL.hpp | 3 +- src/Nazara/Audio/OpenAL.cpp | 3 +- src/Nazara/Network/RUdpConnection.cpp | 2 +- src/Nazara/Renderer/OpenGL.cpp | 3 +- tests/Engine/Core/Serialization.cpp | 261 +++++++++++ tests/resources/Engine/Core/FileTest.txt | 1 + 20 files changed, 747 insertions(+), 22 deletions(-) create mode 100644 examples/Mario/main.cpp create mode 100644 tests/Engine/Core/Serialization.cpp create mode 100644 tests/resources/Engine/Core/FileTest.txt diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index ef697e48a..5d918ef8e 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Ndk diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index e65d8d5d0..f44ff9e8c 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -38,6 +38,7 @@ namespace Ndk s_application = nullptr; } + #ifndef NDK_SERVER template T& Application::AddWindow(Args&&... args) { @@ -46,6 +47,7 @@ namespace Ndk m_windows.emplace_back(new T(std::forward(args)...)); return static_cast(*m_windows.back().get()); } + #endif template World& Application::AddWorld(Args&&... args) diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index f6bd79578..71f8ee2c1 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -2,7 +2,7 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include +#include #include namespace Ndk diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index ec041e4b2..3d5088a7e 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -59,6 +59,7 @@ namespace Ndk application.SetMethod("Quit", &Application::Quit); /*********************************** Ndk::Console **********************************/ + #ifndef NDK_SERVER consoleClass.Inherit(nodeClass, [] (ConsoleHandle* handle) -> Nz::Node* { return handle->GetObject(); @@ -84,6 +85,7 @@ namespace Ndk //consoleClass.SetMethod("SetTextFont", &Console::SetTextFont); consoleClass.SetMethod("Show", &Console::Show, true); + #endif /*********************************** Ndk::Entity **********************************/ entityClass.SetMethod("Enable", &Entity::Enable); @@ -248,4 +250,4 @@ namespace Ndk } instance.SetGlobal("ComponentType"); } -} \ No newline at end of file +} diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 1762f1d12..fc53143dd 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -14,7 +14,7 @@ namespace Ndk { - World::~World() + World::~World() noexcept { // La destruction doit se faire dans un ordre précis Clear(); diff --git a/examples/Mario/main.cpp b/examples/Mario/main.cpp new file mode 100644 index 000000000..24fef574f --- /dev/null +++ b/examples/Mario/main.cpp @@ -0,0 +1,447 @@ +/* +** FirstScene - Première scène graphique +** Prérequis: Aucun +** Utilisation du module utilitaire et graphique +** Présente: +** - 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) +** - Des outils pour afficher une scène basique via le chargement d'un modèle (et son affichage) +** - Éclairage directionnel +** - Gestion d'une caméra free-fly (Avec déplacement fluide) +** - Gestion basique d'une horloge +*/ + +#include // Horloges +#include // Module graphique +#include // Module de rendu +#include // Module utilitaire +#include +#include +#include +#include +#include +#include +#include +#include + +// Petite fonction permettant de rendre le déplacement de la caméra moins ridige +Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength = 3.f); + +int main() +{ + // Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, + // les composants, systèmes, etc. + // 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 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. + // 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 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. + Ndk::World world; + + // Nous pouvons maintenant ajouter des systèmes, mais dans cet exemple nous nous contenterons de ceux de base. + + // La première chose que nous faisons est d'ajouter un background (fond) à notre scène. + // Il en existe plusieurs types, le moteur inclut pour l'instant trois d'entre eux: + // -ColorBackground: Une couleur unie en fond + // -SkyboxBackground: Une skybox en fond, un cube à six faces rendu autour de la caméra (En perdant la notion de distance) + // -TextureBackground: Une texture en fond, celle-ci sera affichée derrière la scène + + // Nous choisirons ici une Skybox, cette dernière étant l'effet le plus réussi et convenant très bien à une scène spatiale + // Pour commencer il faut charger une texture de type cubemap, certaines images sont assemblées de cette façon, + // comme celle que nous allons utiliser. + // En réalité les textures "cubemap" regroupent six faces en une, pour faciliter leur utilisation. + + // Nous créons une nouvelle texture et prenons une référence sur celle-ci (à la manière des pointeurs intelligents) + Nz::TextureRef texture = Nz::Texture::New(); + if (texture->LoadCubemapFromFile("resources/skybox-space.png")) + { + // Si la création du cubemap a fonctionné + + // Nous créons alors le background à partir de notre texture (celui-ci va référencer notre texture, notre pointeur ne sert alors plus à rien). + Nz::SkyboxBackgroundRef skybox = Nz::SkyboxBackground::New(std::move(texture)); + + // Accédons maintenant au système de rendu faisant partie du monde + Ndk::RenderSystem& renderSystem = world.GetSystem(); // 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 + // La notion "par défaut" existe parce qu'une caméra pourrait utiliser son propre fond lors du rendu, + // le fond par défaut est utilisé lorsque la caméra n'a pas de fond propre assigné + renderSystem.SetDefaultBackground(std::move(skybox)); + + // Notre skybox est maintenant référencée par le système, lui-même appartenant au monde, aucune libération explicite n'est nécessaire + } + else + // Le chargement a échoué + std::cout << "Failed to load skybox" << std::endl; + + // Ensuite, nous allons rajouter un modèle à notre scène. + + // Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. + // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?) + + // Encore une fois, nous récupérons une référence plutôt que l'objet lui-même (cela va être très utile par la suite) + Nz::ModelRef spaceshipModel = Nz::Model::New(); + + // Nous allons charger notre modèle depuis un fichier, mais nous pouvons ajuster le modèle lors du chargement via + // une structure permettant de paramétrer le chargement des modèles + Nz::ModelParameters params; + + // 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. + // 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 + + // 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 + params.mesh.flipUVs = true; + + // Nazara va par défaut optimiser les modèles pour un rendu plus rapide, cela peut prendre du temps et n'est pas nécessaire ici + params.mesh.optimizeIndexBuffers = false; + + // On charge ensuite le modèle depuis son fichier + // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) + if (!spaceshipModel->LoadFromFile("resources/Spaceship/spaceship.obj", params)) + { + // Si le chargement a échoué (fichier inexistant/invalide), il ne sert à rien de continuer + std::cout << "Failed to load spaceship" << std::endl; + std::getchar(); + + return EXIT_FAILURE; + } + + // Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles + // Pour cela, nous devons accéder au mesh (maillage 3D) + + // Note: Si nous voulions stocker le mesh pour nous en servir après, nous devrions alors récupérer une référence pour nous assurer + // qu'il ne sera pas supprimé tant que nous l'utilisons, mais ici nous faisons un accès direct et ne nous servons plus du pointeur par la suite + // Il est donc acceptable d'utiliser un pointeur nu ici. + Nz::Mesh* mesh = spaceshipModel->GetMesh(); + std::cout << mesh->GetVertexCount() << " sommets" << std::endl; + std::cout << mesh->GetTriangleCount() << " triangles" << std::endl; + + // En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement + // Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse, + // celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même) + Nz::Material* material = spaceshipModel->GetMaterial(1); // Encore une fois nous ne faisons qu'un accès direct. + + // On lui indique ensuite le chemin vers la normal map + if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png")) + { + // Le chargement a échoué, peut-être le fichier n'existe pas, ou n'est pas reconnu par le moteur + // Mais ce n'est pas une erreur critique, le rendu peut quand même se faire (Mais sera moins détaillé) + std::cout << "Failed to load normal map" << std::endl; + } + + // 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é. + 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. + // Pour des raisons techniques, le pointeur de l'entité peut venir à changer, ou l'entité être simplement détruite pour n'importe quelle raison. + // Le Handle nous permet de maintenir un pointeur valide vers notre entité, et invalidé automatiquement à sa mort. + + // Nous avons désormais une entité, mais celle-ci ne contient rien et n'a d'autre propriété qu'un identifiant + // Nous devons donc lui rajouter les composants que nous voulons. + + // Un NodeComponent donne à notre entité une position, rotation, échelle, et nous permet de l'attacher à d'autres entités (ce que nous ne ferons pas ici). + // É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éé. + spaceship->AddComponent(); + + // Bien, notre entité nouvellement créé dispose maintenant d'une position dans la scène, mais est toujours invisible + // Nous lui ajoutons donc un GraphicsComponent + Ndk::GraphicsComponent& spaceshipGraphics = spaceship->AddComponent(); + + // Ce composant sert de point d'attache pour tous les renderables instanciés (tels que les modèles, les sprites, le texte, etc.) + // Cela signifie également qu'un modèle peut être attaché à autant d'entités que nécessaire. + // Note: Afin de maximiser les performances, essayez d'avoir le moins de renderables instanciés/matériaux et autres ressources possible + // le moteur fonctionne selon le batching et regroupera par exemple tous les modèles identiques ensembles lors du rendu. + spaceshipGraphics.Attach(spaceshipModel); + + // Nous avons besoin également d'une caméra pour servir de point de vue à notre scène, celle-ci sera à l'écart du modèle + // regardant dans sa direction. + + // On conserve la rotation à part via des angles d'eulers pour la caméra free-fly + Nz::EulerAnglesf camAngles(0.f, -20.f, 0.f); + + // 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. + Ndk::EntityHandle camera = world.CreateEntity(); + + // Notre caméra a elle aussi besoin d'être positionnée dans la scène + Ndk::NodeComponent& cameraNode = camera->AddComponent(); + cameraNode.SetPosition(0.f, 0.25f, 2.f); // On place la caméra à l'écart + cameraNode.SetRotation(camAngles); + + // Et dispose d'un composant pour chaque point de vue de la scène, le CameraComponent + Ndk::CameraComponent& cameraComp = camera->AddComponent(); + + // 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) + + // La distance entre l'oeil et le plan éloigné + cameraComp.SetZFar(5000.f); + + // La distance entre l'oeil et le plan rapproché (0 est une valeur interdite car la division par zéro l'est également) + cameraComp.SetZNear(0.1f); + + // Attention que le ratio entre les deux (zFar/zNear) doit rester raisonnable, dans le cas contraire vous risquez un phénomène + // de "Z-Fighting" (Impossibilité de déduire quelle surface devrait apparaître en premier) sur les surfaces éloignées. + + // Il ne nous manque plus maintenant que de l'éclairage, sans quoi la scène sera complètement noire + // Il existe trois types de lumières: + // -DirectionalLight: Lumière infinie sans position, envoyant de la lumière dans une direction particulière + // -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions + // -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion + + // 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é + Ndk::EntityHandle nebulaLight = world.CreateEntity(); + + // Lui ajoutons une position dans la scène + Ndk::NodeComponent& nebulaLightNode = nebulaLight->AddComponent(); + + // Et ensuite le composant principal, le LightComponent + Ndk::LightComponent& nebulaLightComp = nebulaLight->AddComponent(Nz::LightType_Directional); + + // Il nous faut ensuite configurer la lumière + // Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs + nebulaLightComp.SetColor(Nz::Color(255, 182, 90)); + + // Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse + nebulaLightNode.SetRotation(Nz::EulerAnglesf(0.f, 102.f, 0.f)); + + // Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus + // Celle-ci demande des paramètres plus complexes + + // Pour commencer le mode vidéo, celui-ci va définir la taille de la zone de rendu et le nombre de bits par pixels + Nz::VideoMode mode = Nz::VideoMode::GetDesktopMode(); // Nous récupérons le mode vidéo du bureau + + // Nous allons prendre les trois quarts de la résolution du bureau pour notre fenêtre + mode.width = 3 * mode.width / 4; + mode.height = 3 * mode.height / 4; + + // Maintenant le titre, rien de plus simple... + Nz::String windowTitle = "Nazara Demo - First scene"; + + // Ensuite, le "style" de la fenêtre, possède-t-elle des bordures, peut-on cliquer sur la croix de fermeture, + // peut-on la redimensionner, ... + Nz::WindowStyleFlags style = Nz::WindowStyle_Default; // Nous prenons le style par défaut, autorisant tout ce que je viens de citer + + // Ensuite, les paramètres du contexte de rendu + // On peut configurer le niveau d'antialiasing, le nombre de bits du depth buffer et le nombre de bits du stencil buffer + // Nous désirons avoir un peu d'antialiasing (4x), les valeurs par défaut pour le reste nous conviendrons très bien + Nz::RenderTargetParameters parameters; + parameters.antialiasingLevel = 4; + + Nz::RenderWindow window(mode, windowTitle, style, parameters); + if (!window.IsValid()) + { + std::cout << "Failed to create render window" << std::endl; + std::getchar(); + + return EXIT_FAILURE; + } + + // On fait disparaître le curseur de la souris + window.SetCursor(Nz::WindowCursor_None); + + // On lie la caméra à la fenêtre + cameraComp.SetTarget(&window); + + // Et on créé deux horloges pour gérer le temps + Nz::Clock secondClock, updateClock; + Nz::UInt64 updateAccumulator = 0; + + // Ainsi qu'un compteur de FPS improvisé + unsigned int fps = 0; + + // Quelques variables de plus pour notre caméra + bool smoothMovement = true; + Nz::Vector3f targetPos = cameraNode.GetPosition(); + + // Début de la boucle de rendu du programme + while (window.IsOpen()) + { + // Ensuite nous allons traiter les évènements (Étape indispensable pour la fenêtre) + Nz::WindowEvent event; + while (window.PollEvent(&event)) + { + switch (event.type) + { + case Nz::WindowEventType_MouseMoved: // La souris a bougé + { + // Gestion de la caméra free-fly (Rotation) + float sensitivity = 0.3f; // Sensibilité de la souris + + // On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris + camAngles.yaw = Nz::NormalizeAngle(camAngles.yaw - event.mouseMove.deltaX*sensitivity); + + // Idem, mais pour éviter les problèmes de calcul de la matrice de vue, on restreint les angles + camAngles.pitch = Nz::Clamp(camAngles.pitch - event.mouseMove.deltaY*sensitivity, -89.f, 89.f); + + // On applique les angles d'Euler à notre caméra + cameraNode.SetRotation(camAngles); + + // 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 + Nz::Mouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window); + break; + } + + 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) + break; + + case Nz::WindowEventType_KeyPressed: // Une touche a été pressée ! + if (event.key.code == Nz::Keyboard::Key::Escape) + window.Close(); + else if (event.key.code == Nz::Keyboard::F1) + { + if (smoothMovement) + { + targetPos = cameraNode.GetPosition(); + smoothMovement = false; + } + else + smoothMovement = true; + } + break; + + default: + break; + } + } + + Nz::UInt64 elapsedUS = updateClock.GetMicroseconds(); + // On relance l'horloge + updateClock.Restart(); + + // Mise à jour (Caméra) + const Nz::UInt64 updateRate = 1000000 / 60; // 60 fois par seconde + updateAccumulator += elapsedUS; + + if (updateAccumulator >= updateRate) + { + // Le temps écoulé en seconde depuis la dernière fois que ce bloc a été exécuté + float elapsedTime = updateAccumulator / 1000000.f; + std::cout << elapsedTime << std::endl; + + // Vitesse de déplacement de la caméra + float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde + + // Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space)) + cameraSpeed *= 2.f; + + // Pour que nos déplacement soient liés à la rotation de la caméra, nous allons utiliser + // les directions locales de la caméra + + // Si la flèche du haut ou la touche Z (vive ZQSD) est pressée, on avance + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) + targetPos += cameraNode.GetForward() * cameraSpeed; + + // Si la flèche du bas ou la touche S est pressée, on recule + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S)) + targetPos += cameraNode.GetBackward() * cameraSpeed; + + // Etc... + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q)) + targetPos += cameraNode.GetLeft() * cameraSpeed; + + // Etc... + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D)) + targetPos += cameraNode.GetRight() * cameraSpeed; + + // Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation) + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift)) + targetPos += Nz::Vector3f::Up() * cameraSpeed; + + // 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)) + 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 + // Note: La plupart des systèmes, à l'exception de celui de rendu, ont une fréquence de mise à jour fixe (modifiable) + // 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 + // Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering) + window.Display(); + + // On incrémente le compteur de FPS improvisé + fps++; + + if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes + { + // Et on insère ces données dans le titre de la fenêtre + window.SetTitle(windowTitle + " - " + Nz::String::Number(fps) + " FPS"); + + /* + Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier, + via quelque chose de similaire à u8"Cha\u00CEne de caract\u00E8res". + Cependant, si le code source est encodé en UTF-8 (Comme c'est le cas dans ce fichier), + cela fonctionnera aussi comme ceci : "Chaîne de caractères". + */ + + // Et on réinitialise le compteur de FPS + fps = 0; + + // Et on relance l'horloge pour refaire ça dans une seconde + secondClock.Restart(); + } + } + + return EXIT_SUCCESS; +} + +Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength) +{ + // Je ne suis pas l'auteur de cette fonction + // Je l'ai reprise du programme "Floaty Camera Example" et adaptée au C++ + // Trouvé ici: http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/opengl_programming.html#4 + // Tout le mérite revient à l'auteur (Qui me permettra ainsi d'améliorer les démos, voire même le moteur) + + // calculate the displacement between the target and the current position + Nz::Vector3f displacement = targetPos - currentPos; + + // whats the distance between them? + float displacementLength = displacement.GetLength(); + + // Stops small position fluctuations (integration errors probably - since only using euler) + if (Nz::NumberEquals(displacementLength, 0.f)) + return currentPos; + + float invDisplacementLength = 1.f/displacementLength; + + const float dampConstant = 0.000065f; // Something v.small to offset 1/ displacement length + + // the strength of the spring increases the further away the camera is from the target. + float springMagitude = springStrength*displacementLength + dampConstant*invDisplacementLength; + + // Normalise the displacement and scale by the spring magnitude + // and the amount of time passed + float scalar = std::min(invDisplacementLength * springMagitude * frametime, 1.f); + displacement *= scalar; + + // move the camera a bit towards the target + return currentPos + displacement; +} diff --git a/include/Nazara/Audio/OpenAL.hpp b/include/Nazara/Audio/OpenAL.hpp index 5d6fa2634..eab95e6d0 100644 --- a/include/Nazara/Audio/OpenAL.hpp +++ b/include/Nazara/Audio/OpenAL.hpp @@ -87,7 +87,6 @@ namespace Nz static bool OpenDevice(); static OpenALFunc LoadEntry(const char* name, bool throwException = false); }; -} // al NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFER3F alBuffer3f; @@ -186,6 +185,8 @@ NAZARA_AUDIO_API extern OpenALDetail::LPALCOPENDEVICE alcOpenDevice; NAZARA_AUDIO_API extern OpenALDetail::LPALCPROCESSCONTEXT alcProcessContext; NAZARA_AUDIO_API extern OpenALDetail::LPALCSUSPENDCONTEXT alcSuspendContext; +} + #endif // NAZARA_AUDIO_OPENAL #endif // NAZARA_OPENAL_HPP diff --git a/include/Nazara/Core/ResourceSaver.hpp b/include/Nazara/Core/ResourceSaver.hpp index be2880cd0..05b6d7175 100644 --- a/include/Nazara/Core/ResourceSaver.hpp +++ b/include/Nazara/Core/ResourceSaver.hpp @@ -27,6 +27,7 @@ namespace Nz friend Type; public: + using ExtensionGetter = bool (*)(const String& extension); using FormatQuerier = bool (*)(const String& format); using FileSaver = bool (*)(const Type& resource, const String& filePath, const Parameters& parameters); using StreamSaver = bool (*)(const Type& resource, const String& format, Stream& stream, const Parameters& parameters); diff --git a/include/Nazara/Core/ResourceSaver.inl b/include/Nazara/Core/ResourceSaver.inl index 954b86a0e..11d3f2a44 100644 --- a/include/Nazara/Core/ResourceSaver.inl +++ b/include/Nazara/Core/ResourceSaver.inl @@ -28,7 +28,7 @@ namespace Nz { for (Saver& saver : Type::s_savers) { - ExtensionGetter isExtensionSupported = std::get<0>(loader); + ExtensionGetter isExtensionSupported = std::get<0>(saver); if (isExtensionSupported && isExtensionSupported(extension)) return true; diff --git a/include/Nazara/Graphics/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index 427548dc0..95ce2872a 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -30,7 +30,7 @@ namespace Nz SkyboxBackground(TextureRef cubemapTexture = TextureRef()); ~SkyboxBackground() = default; - void Draw(const AbstractViewer* viewer) const; + void Draw(const AbstractViewer* viewer) const override; BackgroundType GetBackgroundType() const override; inline const Vector3f& GetMovementOffset() const; diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 15107e755..a1efd8364 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -636,7 +636,7 @@ namespace Nz if (extend > Extend_Max) return false; - boundingVolume->extend = extend; + boundingVolume->extend = static_cast(extend); if (!Unserialize(context, &boundingVolume->aabb)) return false; diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index e170c2e55..2e51c0bd6 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -55,6 +55,11 @@ namespace Nz String ToString() const; + template + friend bool Serialize(SerializationContext& context, const Frustum& frustum); + template + friend bool Unserialize(SerializationContext& context, Frustum* frustum); + private: Vector3 m_corners[BoxCorner_Max+1]; Plane m_planes[FrustumPlane_Max+1]; @@ -62,9 +67,6 @@ namespace Nz typedef Frustum Frustumd; typedef Frustum Frustumf; - - template bool Serialize(SerializationContext& context, const Frustum& frustum); - template bool Unserialize(SerializationContext& context, Frustum* frustum); } template diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 2e78682d1..b9f56c1e1 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -688,13 +688,13 @@ namespace Nz { for (unsigned int i = 0; i <= BoxCorner_Max; ++i) { - if (!Serialize(context, m_corners[i])) + if (!Serialize(context, frustum.m_corners[i])) return false; } for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) { - if (!Serialize(context, m_planes[i])) + if (!Serialize(context, frustum.m_planes[i])) return false; } @@ -702,24 +702,24 @@ namespace Nz } /*! - * \brief Unserializes a Matrix4 + * \brief Unserializes a Frustum * \return true if successfully unserialized * * \param context Serialization context - * \param matrix Output matrix + * \param matrix Output frustum */ template bool Unserialize(SerializationContext& context, Frustum* frustum) { for (unsigned int i = 0; i <= BoxCorner_Max; ++i) { - if (!Unserialize(context, &m_corners[i])) + if (!Unserialize(context, &frustum->m_corners[i])) return false; } for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) { - if (!Unserialize(context, &m_planes[i])) + if (!Unserialize(context, &frustum->m_planes[i])) return false; } diff --git a/include/Nazara/Network/RUdpConnection.hpp b/include/Nazara/Network/RUdpConnection.hpp index 20285b6fc..2896ec6ce 100644 --- a/include/Nazara/Network/RUdpConnection.hpp +++ b/include/Nazara/Network/RUdpConnection.hpp @@ -119,6 +119,10 @@ namespace Nz struct PeerData //TODO: Move this to RUdpClient { + PeerData() = default; + PeerData(PeerData&& other) = default; + PeerData& operator=(PeerData&& other) = default; + std::array, PacketPriority_Max + 1> pendingPackets; std::deque pendingAckQueue; std::set receivedQueue; @@ -153,6 +157,6 @@ namespace Nz }; } -#include +#include -#endif // NAZARA_RUDPSERVER_HPP \ No newline at end of file +#endif // NAZARA_RUDPSERVER_HPP diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 403a7a534..94d7f891d 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -153,7 +153,6 @@ namespace Nz static void OnContextChanged(const Context* newContext); static void OnContextDestruction(const Context* context); }; -} NAZARA_RENDERER_API extern PFNGLACTIVETEXTUREPROC glActiveTexture; NAZARA_RENDERER_API extern PFNGLATTACHSHADERPROC glAttachShader; @@ -336,6 +335,8 @@ NAZARA_RENDERER_API extern GLX::PFNGLXSWAPINTERVALMESAPROC NzglXSwapInter NAZARA_RENDERER_API extern GLX::PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; #endif +} + #endif // NAZARA_RENDERER_OPENGL #endif // NAZARA_OPENGL_HPP diff --git a/src/Nazara/Audio/OpenAL.cpp b/src/Nazara/Audio/OpenAL.cpp index 1c30cd5f1..f527b682d 100644 --- a/src/Nazara/Audio/OpenAL.cpp +++ b/src/Nazara/Audio/OpenAL.cpp @@ -372,7 +372,6 @@ namespace Nz return entry; } -} // al OpenALDetail::LPALBUFFER3F alBuffer3f = nullptr; @@ -470,3 +469,5 @@ OpenALDetail::LPALCMAKECONTEXTCURRENT alcMakeContextCurrent = nullptr; OpenALDetail::LPALCOPENDEVICE alcOpenDevice = nullptr; OpenALDetail::LPALCPROCESSCONTEXT alcProcessContext = nullptr; OpenALDetail::LPALCSUSPENDCONTEXT alcSuspendContext = nullptr; + +} diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp index 12fdc3d22..be2bec015 100644 --- a/src/Nazara/Network/RUdpConnection.cpp +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 5cc0865ea..0834999bc 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -2078,7 +2078,6 @@ namespace Nz }; static_assert(VertexComponent_Max + 1 == 16, "Attribute index array is incomplete"); -} PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr; PFNGLATTACHSHADERPROC glAttachShader = nullptr; @@ -2260,3 +2259,5 @@ GLX::PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; GLX::PFNGLXSWAPINTERVALMESAPROC NzglXSwapIntervalMESA = nullptr; GLX::PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; #endif + +} diff --git a/tests/Engine/Core/Serialization.cpp b/tests/Engine/Core/Serialization.cpp new file mode 100644 index 000000000..299b9cc8f --- /dev/null +++ b/tests/Engine/Core/Serialization.cpp @@ -0,0 +1,261 @@ +#include + +#include +#include +#include +#include +#include + +#include + +SCENARIO("Serialization", "[CORE][SERIALIZATION]") +{ + GIVEN("A context of serialization") + { + std::array datas; // The array must be bigger than any of the serializable classes + Nz::MemoryView stream(datas.data(), datas.size()); + + Nz::SerializationContext context; + context.stream = &stream; + + WHEN("We serialize basic types") + { + THEN("Arithmetical types") + { + context.stream->SetCursorPos(0); + REQUIRE(Serialize(context, 3)); + int value = 0; + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &value)); + REQUIRE(value == 3); + } + + THEN("Boolean type") + { + context.stream->SetCursorPos(0); + REQUIRE(Serialize(context, true)); + context.stream->SetCursorPos(0); + bool value = false; + REQUIRE(Unserialize(context, &value)); + REQUIRE(value == true); + } + } + + WHEN("We serialize mathematical classes") + { + THEN("BoudingVolume") + { + context.stream->SetCursorPos(0); + Nz::BoundingVolumef nullVolume = Nz::BoundingVolumef::Null(); + Nz::BoundingVolumef copy(nullVolume); + REQUIRE(Serialize(context, nullVolume)); + nullVolume = Nz::BoundingVolumef::Infinite(); + REQUIRE(nullVolume != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &nullVolume)); + REQUIRE(nullVolume == copy); + } + + THEN("Box") + { + context.stream->SetCursorPos(0); + Nz::Boxf zeroBox = Nz::Boxf::Zero(); + Nz::Boxf copy(zeroBox); + REQUIRE(Serialize(context, zeroBox)); + zeroBox = Nz::Boxf(1, 1, 1, 1, 1, 1); + REQUIRE(zeroBox != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &zeroBox)); + REQUIRE(zeroBox == copy); + } + + THEN("EulerAngles") + { + context.stream->SetCursorPos(0); + Nz::EulerAnglesf zeroEuler = Nz::EulerAnglesf::Zero(); + Nz::EulerAnglesf copy(zeroEuler); + REQUIRE(Serialize(context, zeroEuler)); + zeroEuler = Nz::EulerAnglesf(10, 24, 6); // Random values + REQUIRE(zeroEuler != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &zeroEuler)); + REQUIRE(zeroEuler == copy); + } + + THEN("Frustum") + { + context.stream->SetCursorPos(0); + Nz::Frustumf frustum; + frustum.Build(10, 10, 10, 100, Nz::Vector3f::UnitX(), Nz::Vector3f::UnitZ()); // Random values + Nz::Frustumf copy(frustum); + REQUIRE(Serialize(context, frustum)); + frustum.Build(50, 40, 20, 100, Nz::Vector3f::UnitX(), Nz::Vector3f::UnitZ()); + for (unsigned int i = 0; i <= Nz::BoxCorner_Max; ++i) + REQUIRE(frustum.GetCorner(static_cast(i)) != copy.GetCorner(static_cast(i))); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &frustum)); + for (unsigned int i = 0; i <= Nz::BoxCorner_Max; ++i) + REQUIRE(frustum.GetCorner(static_cast(i)) == copy.GetCorner(static_cast(i))); + } + + THEN("Matrix4") + { + context.stream->SetCursorPos(0); + Nz::Matrix4f zeroMatrix = Nz::Matrix4f::Zero(); + Nz::Matrix4f copy(zeroMatrix); + REQUIRE(Serialize(context, zeroMatrix)); + zeroMatrix = Nz::Matrix4f::Identity(); // Random values + REQUIRE(zeroMatrix != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &zeroMatrix)); + REQUIRE(zeroMatrix == copy); + } + + THEN("OrientedBox") + { + context.stream->SetCursorPos(0); + Nz::OrientedBoxf zeroOBB = Nz::OrientedBoxf::Zero(); + Nz::OrientedBoxf copy(zeroOBB); + REQUIRE(Serialize(context, zeroOBB)); + zeroOBB = Nz::OrientedBoxf(1, 1, 1, 1, 1, 1); // Random values + REQUIRE(zeroOBB != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &zeroOBB)); + REQUIRE(zeroOBB == copy); + } + + THEN("Plane") + { + context.stream->SetCursorPos(0); + Nz::Planef planeXY = Nz::Planef::XY(); + Nz::Planef copy(planeXY); + REQUIRE(Serialize(context, planeXY)); + planeXY = Nz::Planef::YZ(); + REQUIRE(planeXY != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &planeXY)); + REQUIRE(planeXY == copy); + } + + THEN("Quaternion") + { + context.stream->SetCursorPos(0); + Nz::Quaternionf quaternionIdentity = Nz::Quaternionf::Identity(); + Nz::Quaternionf copy(quaternionIdentity); + REQUIRE(Serialize(context, quaternionIdentity)); + quaternionIdentity = Nz::Quaternionf::Zero(); + REQUIRE(quaternionIdentity != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &quaternionIdentity)); + REQUIRE(quaternionIdentity == copy); + } + + THEN("Ray") + { + context.stream->SetCursorPos(0); + Nz::Rayf axisX = Nz::Rayf::AxisX(); + Nz::Rayf copy(axisX); + REQUIRE(Serialize(context, axisX)); + axisX = Nz::Rayf::AxisY(); + REQUIRE(axisX != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &axisX)); + REQUIRE(axisX == copy); + } + + THEN("Rect") + { + context.stream->SetCursorPos(0); + Nz::Rectf zeroRect = Nz::Rectf::Zero(); + Nz::Rectf copy(zeroRect); + REQUIRE(Serialize(context, zeroRect)); + zeroRect = Nz::Rectf(1, 1, 1, 1); // Random values + REQUIRE(zeroRect != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &zeroRect)); + REQUIRE(zeroRect == copy); + } + + THEN("Sphere") + { + context.stream->SetCursorPos(0); + Nz::Spheref zeroSphere = Nz::Spheref::Zero(); + Nz::Spheref copy(zeroSphere); + REQUIRE(Serialize(context, zeroSphere)); + zeroSphere = Nz::Spheref::Unit(); + REQUIRE(zeroSphere != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &zeroSphere)); + REQUIRE(zeroSphere == copy); + } + + THEN("Vector2") + { + context.stream->SetCursorPos(0); + Nz::Vector2f unitX = Nz::Vector2f::UnitX(); + Nz::Vector2f copy(unitX); + REQUIRE(Serialize(context, unitX)); + unitX = Nz::Vector2f::UnitY(); + REQUIRE(unitX != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &unitX)); + REQUIRE(unitX == copy); + } + + THEN("Vector3") + { + context.stream->SetCursorPos(0); + Nz::Vector3f unitX = Nz::Vector3f::UnitX(); + Nz::Vector3f copy(unitX); + REQUIRE(Serialize(context, unitX)); + unitX = Nz::Vector3f::UnitY(); + REQUIRE(unitX != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &unitX)); + REQUIRE(unitX == copy); + } + + THEN("Vector4") + { + context.stream->SetCursorPos(0); + Nz::Vector4f unitX = Nz::Vector4f::UnitX(); + Nz::Vector4f copy(unitX); + REQUIRE(Serialize(context, unitX)); + unitX = Nz::Vector4f::UnitY(); + REQUIRE(unitX != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &unitX)); + REQUIRE(unitX == copy); + } + } + + WHEN("We serialize core classes") + { + THEN("Color") + { + context.stream->SetCursorPos(0); + Nz::Color red = Nz::Color::Red; + Nz::Color copy(red); + REQUIRE(Serialize(context, red)); + red = Nz::Color::Black; + REQUIRE(red != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &red)); + REQUIRE(red == copy); + } + + THEN("String") + { + context.stream->SetCursorPos(0); + Nz::String string = "string"; + Nz::String copy(string); + REQUIRE(Serialize(context, string)); + string = "another"; + REQUIRE(string != copy); + context.stream->SetCursorPos(0); + REQUIRE(Unserialize(context, &string)); + REQUIRE(string == copy); + } + } + } +} diff --git a/tests/resources/Engine/Core/FileTest.txt b/tests/resources/Engine/Core/FileTest.txt new file mode 100644 index 000000000..345e6aef7 --- /dev/null +++ b/tests/resources/Engine/Core/FileTest.txt @@ -0,0 +1 @@ +Test From 91f2bee48747e1fd05aff2eef1bd0184ba740e55 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 4 Apr 2016 10:36:13 +0200 Subject: [PATCH 212/229] Bug fix -> String with one char + Directory and File on linux Former-commit-id: 7f9b6c44197c3cc67145eb0a2d421a2e1de45a84 --- examples/Mario/main.cpp | 447 ------------------------ include/Nazara/Math/Matrix4.inl | 3 +- src/Nazara/Core/Posix/DirectoryImpl.cpp | 2 +- src/Nazara/Core/Posix/FileImpl.cpp | 6 +- src/Nazara/Core/String.cpp | 8 +- src/Nazara/Network/RUdpConnection.cpp | 2 +- tests/Engine/Core/File.cpp | 36 +- tests/Engine/Core/String.cpp | 15 + 8 files changed, 60 insertions(+), 459 deletions(-) delete mode 100644 examples/Mario/main.cpp diff --git a/examples/Mario/main.cpp b/examples/Mario/main.cpp deleted file mode 100644 index 24fef574f..000000000 --- a/examples/Mario/main.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/* -** FirstScene - Première scène graphique -** Prérequis: Aucun -** Utilisation du module utilitaire et graphique -** Présente: -** - 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) -** - Des outils pour afficher une scène basique via le chargement d'un modèle (et son affichage) -** - Éclairage directionnel -** - Gestion d'une caméra free-fly (Avec déplacement fluide) -** - Gestion basique d'une horloge -*/ - -#include // Horloges -#include // Module graphique -#include // Module de rendu -#include // Module utilitaire -#include -#include -#include -#include -#include -#include -#include -#include - -// Petite fonction permettant de rendre le déplacement de la caméra moins ridige -Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength = 3.f); - -int main() -{ - // Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, - // les composants, systèmes, etc. - // 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 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. - // 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 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. - Ndk::World world; - - // Nous pouvons maintenant ajouter des systèmes, mais dans cet exemple nous nous contenterons de ceux de base. - - // La première chose que nous faisons est d'ajouter un background (fond) à notre scène. - // Il en existe plusieurs types, le moteur inclut pour l'instant trois d'entre eux: - // -ColorBackground: Une couleur unie en fond - // -SkyboxBackground: Une skybox en fond, un cube à six faces rendu autour de la caméra (En perdant la notion de distance) - // -TextureBackground: Une texture en fond, celle-ci sera affichée derrière la scène - - // Nous choisirons ici une Skybox, cette dernière étant l'effet le plus réussi et convenant très bien à une scène spatiale - // Pour commencer il faut charger une texture de type cubemap, certaines images sont assemblées de cette façon, - // comme celle que nous allons utiliser. - // En réalité les textures "cubemap" regroupent six faces en une, pour faciliter leur utilisation. - - // Nous créons une nouvelle texture et prenons une référence sur celle-ci (à la manière des pointeurs intelligents) - Nz::TextureRef texture = Nz::Texture::New(); - if (texture->LoadCubemapFromFile("resources/skybox-space.png")) - { - // Si la création du cubemap a fonctionné - - // Nous créons alors le background à partir de notre texture (celui-ci va référencer notre texture, notre pointeur ne sert alors plus à rien). - Nz::SkyboxBackgroundRef skybox = Nz::SkyboxBackground::New(std::move(texture)); - - // Accédons maintenant au système de rendu faisant partie du monde - Ndk::RenderSystem& renderSystem = world.GetSystem(); // 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 - // La notion "par défaut" existe parce qu'une caméra pourrait utiliser son propre fond lors du rendu, - // le fond par défaut est utilisé lorsque la caméra n'a pas de fond propre assigné - renderSystem.SetDefaultBackground(std::move(skybox)); - - // Notre skybox est maintenant référencée par le système, lui-même appartenant au monde, aucune libération explicite n'est nécessaire - } - else - // Le chargement a échoué - std::cout << "Failed to load skybox" << std::endl; - - // Ensuite, nous allons rajouter un modèle à notre scène. - - // Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. - // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?) - - // Encore une fois, nous récupérons une référence plutôt que l'objet lui-même (cela va être très utile par la suite) - Nz::ModelRef spaceshipModel = Nz::Model::New(); - - // Nous allons charger notre modèle depuis un fichier, mais nous pouvons ajuster le modèle lors du chargement via - // une structure permettant de paramétrer le chargement des modèles - Nz::ModelParameters params; - - // 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. - // 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 - - // 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 - params.mesh.flipUVs = true; - - // Nazara va par défaut optimiser les modèles pour un rendu plus rapide, cela peut prendre du temps et n'est pas nécessaire ici - params.mesh.optimizeIndexBuffers = false; - - // On charge ensuite le modèle depuis son fichier - // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) - if (!spaceshipModel->LoadFromFile("resources/Spaceship/spaceship.obj", params)) - { - // Si le chargement a échoué (fichier inexistant/invalide), il ne sert à rien de continuer - std::cout << "Failed to load spaceship" << std::endl; - std::getchar(); - - return EXIT_FAILURE; - } - - // Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles - // Pour cela, nous devons accéder au mesh (maillage 3D) - - // Note: Si nous voulions stocker le mesh pour nous en servir après, nous devrions alors récupérer une référence pour nous assurer - // qu'il ne sera pas supprimé tant que nous l'utilisons, mais ici nous faisons un accès direct et ne nous servons plus du pointeur par la suite - // Il est donc acceptable d'utiliser un pointeur nu ici. - Nz::Mesh* mesh = spaceshipModel->GetMesh(); - std::cout << mesh->GetVertexCount() << " sommets" << std::endl; - std::cout << mesh->GetTriangleCount() << " triangles" << std::endl; - - // En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement - // Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse, - // celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même) - Nz::Material* material = spaceshipModel->GetMaterial(1); // Encore une fois nous ne faisons qu'un accès direct. - - // On lui indique ensuite le chemin vers la normal map - if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png")) - { - // Le chargement a échoué, peut-être le fichier n'existe pas, ou n'est pas reconnu par le moteur - // Mais ce n'est pas une erreur critique, le rendu peut quand même se faire (Mais sera moins détaillé) - std::cout << "Failed to load normal map" << std::endl; - } - - // 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é. - 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. - // Pour des raisons techniques, le pointeur de l'entité peut venir à changer, ou l'entité être simplement détruite pour n'importe quelle raison. - // Le Handle nous permet de maintenir un pointeur valide vers notre entité, et invalidé automatiquement à sa mort. - - // Nous avons désormais une entité, mais celle-ci ne contient rien et n'a d'autre propriété qu'un identifiant - // Nous devons donc lui rajouter les composants que nous voulons. - - // Un NodeComponent donne à notre entité une position, rotation, échelle, et nous permet de l'attacher à d'autres entités (ce que nous ne ferons pas ici). - // É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éé. - spaceship->AddComponent(); - - // Bien, notre entité nouvellement créé dispose maintenant d'une position dans la scène, mais est toujours invisible - // Nous lui ajoutons donc un GraphicsComponent - Ndk::GraphicsComponent& spaceshipGraphics = spaceship->AddComponent(); - - // Ce composant sert de point d'attache pour tous les renderables instanciés (tels que les modèles, les sprites, le texte, etc.) - // Cela signifie également qu'un modèle peut être attaché à autant d'entités que nécessaire. - // Note: Afin de maximiser les performances, essayez d'avoir le moins de renderables instanciés/matériaux et autres ressources possible - // le moteur fonctionne selon le batching et regroupera par exemple tous les modèles identiques ensembles lors du rendu. - spaceshipGraphics.Attach(spaceshipModel); - - // Nous avons besoin également d'une caméra pour servir de point de vue à notre scène, celle-ci sera à l'écart du modèle - // regardant dans sa direction. - - // On conserve la rotation à part via des angles d'eulers pour la caméra free-fly - Nz::EulerAnglesf camAngles(0.f, -20.f, 0.f); - - // 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. - Ndk::EntityHandle camera = world.CreateEntity(); - - // Notre caméra a elle aussi besoin d'être positionnée dans la scène - Ndk::NodeComponent& cameraNode = camera->AddComponent(); - cameraNode.SetPosition(0.f, 0.25f, 2.f); // On place la caméra à l'écart - cameraNode.SetRotation(camAngles); - - // Et dispose d'un composant pour chaque point de vue de la scène, le CameraComponent - Ndk::CameraComponent& cameraComp = camera->AddComponent(); - - // 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) - - // La distance entre l'oeil et le plan éloigné - cameraComp.SetZFar(5000.f); - - // La distance entre l'oeil et le plan rapproché (0 est une valeur interdite car la division par zéro l'est également) - cameraComp.SetZNear(0.1f); - - // Attention que le ratio entre les deux (zFar/zNear) doit rester raisonnable, dans le cas contraire vous risquez un phénomène - // de "Z-Fighting" (Impossibilité de déduire quelle surface devrait apparaître en premier) sur les surfaces éloignées. - - // Il ne nous manque plus maintenant que de l'éclairage, sans quoi la scène sera complètement noire - // Il existe trois types de lumières: - // -DirectionalLight: Lumière infinie sans position, envoyant de la lumière dans une direction particulière - // -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions - // -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion - - // 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é - Ndk::EntityHandle nebulaLight = world.CreateEntity(); - - // Lui ajoutons une position dans la scène - Ndk::NodeComponent& nebulaLightNode = nebulaLight->AddComponent(); - - // Et ensuite le composant principal, le LightComponent - Ndk::LightComponent& nebulaLightComp = nebulaLight->AddComponent(Nz::LightType_Directional); - - // Il nous faut ensuite configurer la lumière - // Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs - nebulaLightComp.SetColor(Nz::Color(255, 182, 90)); - - // Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse - nebulaLightNode.SetRotation(Nz::EulerAnglesf(0.f, 102.f, 0.f)); - - // Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus - // Celle-ci demande des paramètres plus complexes - - // Pour commencer le mode vidéo, celui-ci va définir la taille de la zone de rendu et le nombre de bits par pixels - Nz::VideoMode mode = Nz::VideoMode::GetDesktopMode(); // Nous récupérons le mode vidéo du bureau - - // Nous allons prendre les trois quarts de la résolution du bureau pour notre fenêtre - mode.width = 3 * mode.width / 4; - mode.height = 3 * mode.height / 4; - - // Maintenant le titre, rien de plus simple... - Nz::String windowTitle = "Nazara Demo - First scene"; - - // Ensuite, le "style" de la fenêtre, possède-t-elle des bordures, peut-on cliquer sur la croix de fermeture, - // peut-on la redimensionner, ... - Nz::WindowStyleFlags style = Nz::WindowStyle_Default; // Nous prenons le style par défaut, autorisant tout ce que je viens de citer - - // Ensuite, les paramètres du contexte de rendu - // On peut configurer le niveau d'antialiasing, le nombre de bits du depth buffer et le nombre de bits du stencil buffer - // Nous désirons avoir un peu d'antialiasing (4x), les valeurs par défaut pour le reste nous conviendrons très bien - Nz::RenderTargetParameters parameters; - parameters.antialiasingLevel = 4; - - Nz::RenderWindow window(mode, windowTitle, style, parameters); - if (!window.IsValid()) - { - std::cout << "Failed to create render window" << std::endl; - std::getchar(); - - return EXIT_FAILURE; - } - - // On fait disparaître le curseur de la souris - window.SetCursor(Nz::WindowCursor_None); - - // On lie la caméra à la fenêtre - cameraComp.SetTarget(&window); - - // Et on créé deux horloges pour gérer le temps - Nz::Clock secondClock, updateClock; - Nz::UInt64 updateAccumulator = 0; - - // Ainsi qu'un compteur de FPS improvisé - unsigned int fps = 0; - - // Quelques variables de plus pour notre caméra - bool smoothMovement = true; - Nz::Vector3f targetPos = cameraNode.GetPosition(); - - // Début de la boucle de rendu du programme - while (window.IsOpen()) - { - // Ensuite nous allons traiter les évènements (Étape indispensable pour la fenêtre) - Nz::WindowEvent event; - while (window.PollEvent(&event)) - { - switch (event.type) - { - case Nz::WindowEventType_MouseMoved: // La souris a bougé - { - // Gestion de la caméra free-fly (Rotation) - float sensitivity = 0.3f; // Sensibilité de la souris - - // On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris - camAngles.yaw = Nz::NormalizeAngle(camAngles.yaw - event.mouseMove.deltaX*sensitivity); - - // Idem, mais pour éviter les problèmes de calcul de la matrice de vue, on restreint les angles - camAngles.pitch = Nz::Clamp(camAngles.pitch - event.mouseMove.deltaY*sensitivity, -89.f, 89.f); - - // On applique les angles d'Euler à notre caméra - cameraNode.SetRotation(camAngles); - - // 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 - Nz::Mouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window); - break; - } - - 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) - break; - - case Nz::WindowEventType_KeyPressed: // Une touche a été pressée ! - if (event.key.code == Nz::Keyboard::Key::Escape) - window.Close(); - else if (event.key.code == Nz::Keyboard::F1) - { - if (smoothMovement) - { - targetPos = cameraNode.GetPosition(); - smoothMovement = false; - } - else - smoothMovement = true; - } - break; - - default: - break; - } - } - - Nz::UInt64 elapsedUS = updateClock.GetMicroseconds(); - // On relance l'horloge - updateClock.Restart(); - - // Mise à jour (Caméra) - const Nz::UInt64 updateRate = 1000000 / 60; // 60 fois par seconde - updateAccumulator += elapsedUS; - - if (updateAccumulator >= updateRate) - { - // Le temps écoulé en seconde depuis la dernière fois que ce bloc a été exécuté - float elapsedTime = updateAccumulator / 1000000.f; - std::cout << elapsedTime << std::endl; - - // Vitesse de déplacement de la caméra - float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde - - // Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space)) - cameraSpeed *= 2.f; - - // Pour que nos déplacement soient liés à la rotation de la caméra, nous allons utiliser - // les directions locales de la caméra - - // Si la flèche du haut ou la touche Z (vive ZQSD) est pressée, on avance - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) - targetPos += cameraNode.GetForward() * cameraSpeed; - - // Si la flèche du bas ou la touche S est pressée, on recule - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S)) - targetPos += cameraNode.GetBackward() * cameraSpeed; - - // Etc... - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q)) - targetPos += cameraNode.GetLeft() * cameraSpeed; - - // Etc... - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D)) - targetPos += cameraNode.GetRight() * cameraSpeed; - - // Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation) - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift)) - targetPos += Nz::Vector3f::Up() * cameraSpeed; - - // 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)) - 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 - // Note: La plupart des systèmes, à l'exception de celui de rendu, ont une fréquence de mise à jour fixe (modifiable) - // 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 - // Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering) - window.Display(); - - // On incrémente le compteur de FPS improvisé - fps++; - - if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes - { - // Et on insère ces données dans le titre de la fenêtre - window.SetTitle(windowTitle + " - " + Nz::String::Number(fps) + " FPS"); - - /* - Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier, - via quelque chose de similaire à u8"Cha\u00CEne de caract\u00E8res". - Cependant, si le code source est encodé en UTF-8 (Comme c'est le cas dans ce fichier), - cela fonctionnera aussi comme ceci : "Chaîne de caractères". - */ - - // Et on réinitialise le compteur de FPS - fps = 0; - - // Et on relance l'horloge pour refaire ça dans une seconde - secondClock.Restart(); - } - } - - return EXIT_SUCCESS; -} - -Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength) -{ - // Je ne suis pas l'auteur de cette fonction - // Je l'ai reprise du programme "Floaty Camera Example" et adaptée au C++ - // Trouvé ici: http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/opengl_programming.html#4 - // Tout le mérite revient à l'auteur (Qui me permettra ainsi d'améliorer les démos, voire même le moteur) - - // calculate the displacement between the target and the current position - Nz::Vector3f displacement = targetPos - currentPos; - - // whats the distance between them? - float displacementLength = displacement.GetLength(); - - // Stops small position fluctuations (integration errors probably - since only using euler) - if (Nz::NumberEquals(displacementLength, 0.f)) - return currentPos; - - float invDisplacementLength = 1.f/displacementLength; - - const float dampConstant = 0.000065f; // Something v.small to offset 1/ displacement length - - // the strength of the spring increases the further away the camera is from the target. - float springMagitude = springStrength*displacementLength + dampConstant*invDisplacementLength; - - // Normalise the displacement and scale by the spring magnitude - // and the amount of time passed - float scalar = std::min(invDisplacementLength * springMagitude * frametime, 1.f); - displacement *= scalar; - - // move the camera a bit towards the target - return currentPos + displacement; -} diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index afa8143e3..b0decee2a 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -1792,9 +1792,10 @@ namespace Nz template bool Unserialize(SerializationContext& context, Matrix4* matrix) { + T* head = matrix->operator T*(); for (unsigned int i = 0; i < 16; ++i) { - if (!Unserialize(context, &matrix[i])) + if (!Unserialize(context, head + i)) return false; } diff --git a/src/Nazara/Core/Posix/DirectoryImpl.cpp b/src/Nazara/Core/Posix/DirectoryImpl.cpp index e3add7fd5..e23c82626 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.cpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.cpp @@ -49,7 +49,7 @@ namespace Nz return true; else { - if (errno != ENOENT) + if (errno == EBADF || errno == EOVERFLOW) NazaraError("Unable to get next result: " + Error::GetLastSystemError()); return false; diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 3fa93f6f2..31c1ace73 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -54,11 +54,11 @@ namespace Nz int flags; mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - if (mode & OpenMode_ReadWrite) + if ((mode & OpenMode_ReadWrite) == OpenMode_ReadWrite) flags = O_CREAT | O_RDWR; - else if (mode & OpenMode_ReadOnly) + else if ((mode & OpenMode_ReadOnly) == OpenMode_ReadOnly) flags = O_RDONLY; - else if (mode & OpenMode_WriteOnly) + else if ((mode & OpenMode_WriteOnly) == OpenMode_WriteOnly) flags = O_CREAT | O_WRONLY; else return false; diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 3e72e1dce..b94715457 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -3204,14 +3204,12 @@ namespace Nz EnsureOwnership(true); m_sharedString->size = 1; - m_sharedString->string[0] = character; m_sharedString->string[1] = '\0'; } else - { - auto newString = std::make_shared(1); - newString->string[0] = character; - } + m_sharedString = std::make_shared(1); + + m_sharedString->string[0] = character; } else ReleaseString(); diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp index be2bec015..f8b57cf00 100644 --- a/src/Nazara/Network/RUdpConnection.cpp +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -474,7 +474,7 @@ namespace Nz return true; } - inline void RUdpConnection::Uninitialize() + void RUdpConnection::Uninitialize() { } diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index c00af74d1..2a87c8495 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -9,7 +9,7 @@ SCENARIO("File", "[CORE][FILE]") { Nz::File file("Test File.txt", Nz::OpenMode_ReadWrite); REQUIRE(file.GetDirectory() == Nz::Directory::GetCurrent() + NAZARA_DIRECTORY_SEPARATOR); - CHECK(file.IsOpen()); + REQUIRE(file.IsOpen()); THEN("We are allowed to write 3 times 'Test String'") { @@ -50,4 +50,38 @@ SCENARIO("File", "[CORE][FILE]") } } } + + GIVEN("The test file") + { + REQUIRE(Nz::File::Exists("resources/Engine/Core/FileTest.txt")); + + Nz::File fileTest("resources/Engine/Core/FileTest.txt", Nz::OpenMode_ReadOnly | Nz::OpenMode_Text); + + WHEN("We read the first line of the file") + { + REQUIRE(fileTest.IsOpen()); + Nz::String content = fileTest.ReadLine(); + + THEN("The content must be 'Test'") + { + REQUIRE(content == "Test"); + } + } + } + + GIVEN("Nothing") + { + WHEN("We get the absolute path of something containing relative path") + { + Nz::String containingDot = "/resources/Spaceship/./spaceship.mtl"; + Nz::String containingDoubleDot = "/resources/Spaceship/../Spaceship/spaceship.mtl"; + + THEN("The relative positioning should disappear") + { + Nz::String containingNoMoreDot = "/resources/Spaceship/spaceship.mtl"; + REQUIRE(Nz::File::AbsolutePath(containingDot) == containingNoMoreDot); + REQUIRE(Nz::File::AbsolutePath(containingDoubleDot) == containingNoMoreDot); + } + } + } } diff --git a/tests/Engine/Core/String.cpp b/tests/Engine/Core/String.cpp index a563d0b7f..eac5eaef6 100644 --- a/tests/Engine/Core/String.cpp +++ b/tests/Engine/Core/String.cpp @@ -82,6 +82,21 @@ SCENARIO("String", "[CORE][STRING]") } } + GIVEN("One character string") + { + Nz::String characterString; + + WHEN("We set the string to one character") + { + characterString.Set('/'); + + THEN("The string must contain it") + { + REQUIRE(characterString == '/'); + } + } + } + /* TODO GIVEN("One unicode string") { From 0f135232da18bca6c5596eb775d7b80f602889ed Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 4 Apr 2016 13:47:52 +0200 Subject: [PATCH 213/229] Examples: Add Tut01 https://github.com/DigitalPulseSoftware/NazaraEngine/wiki/(FR)-Tutoriel-01---Hello-World Former-commit-id: 114b03afccb253cbaa05caa3c990359a1b2125b2 --- examples/Tut01/build.lua | 14 ++++++++++ examples/Tut01/main.cpp | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 examples/Tut01/build.lua create mode 100644 examples/Tut01/main.cpp diff --git a/examples/Tut01/build.lua b/examples/Tut01/build.lua new file mode 100644 index 000000000..a4f623662 --- /dev/null +++ b/examples/Tut01/build.lua @@ -0,0 +1,14 @@ +EXAMPLE.Name = "Tut01_HelloWorld" + +EXAMPLE.Console = true + +EXAMPLE.Files = { + "main.cpp" +} + +EXAMPLE.Libraries = { + "NazaraCore", + "NazaraGraphics", + "NazaraUtility", + "NazaraSDK" +} diff --git a/examples/Tut01/main.cpp b/examples/Tut01/main.cpp new file mode 100644 index 000000000..d1ebcd5d4 --- /dev/null +++ b/examples/Tut01/main.cpp @@ -0,0 +1,57 @@ +// Sources pour https://github.com/DigitalPulseSoftware/NazaraEngine/wiki/(FR)-Tutoriel-01---Hello-World + +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + Ndk::Application application; + + Nz::RenderWindow& mainWindow = application.AddWindow(); + mainWindow.Create(Nz::VideoMode(800, 600, 32), "Test"); + + Ndk::World& world = application.AddWorld(); + world.GetSystem().SetGlobalUp(Nz::Vector3f::Down()); + world.GetSystem().SetDefaultBackground(Nz::ColorBackground::New(Nz::Color(192, 100, 100))); + + + Ndk::EntityHandle viewEntity = world.CreateEntity(); + viewEntity->AddComponent(); + + Ndk::CameraComponent& viewer = viewEntity->AddComponent(); + viewer.SetTarget(&mainWindow); + viewer.SetProjectionType(Nz::ProjectionType_Orthogonal); + + + Nz::TextSpriteRef textSprite = Nz::TextSprite::New(); + textSprite->Update(Nz::SimpleTextDrawer::Draw("Hello world !", 72)); + + Ndk::EntityHandle text = world.CreateEntity(); + Ndk::NodeComponent& nodeComponent = text->AddComponent(); + + Ndk::GraphicsComponent& graphicsComponent = text->AddComponent(); + graphicsComponent.Attach(textSprite); + + Nz::Boxf textBox = graphicsComponent.GetBoundingVolume().aabb; + nodeComponent.SetPosition(mainWindow.GetWidth() / 2 - textBox.width / 2, mainWindow.GetHeight() / 2 - textBox.height / 2); + + while (application.Run()) + { + Nz::WindowEvent event; + while (mainWindow.PollEvent(&event)) + { + if (event.type == Nz::WindowEventType_Quit) + application.Quit(); + } + + mainWindow.Display(); + } + + return EXIT_SUCCESS; +} From 5f823c9126aee9a917bb9cb8563535d8221b91d5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Apr 2016 12:47:13 +0200 Subject: [PATCH 214/229] Renderer/Renderer: Add default UV to fullscreen quad buffer Fixes TextureBackground Former-commit-id: c9533df4b1e30229d88aad9afa7a2ddb22a9c4e1 --- src/Nazara/Renderer/Renderer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 57cc8522f..2017e2924 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -623,14 +623,14 @@ namespace Nz s_updateFlags = Update_Matrices | Update_Shader | Update_VAO; s_vertexBuffer = nullptr; - s_fullscreenQuadBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + s_fullscreenQuadBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY_UV), 4, DataStorage_Hardware, BufferUsage_Static); - float vertices[4 * 2] = + float vertices[4 * 2 * 2] = { - -1.f, -1.f, - 1.f, -1.f, - -1.f, 1.f, - 1.f, 1.f, + -1.f, -1.f, 0.f, 1.f, + 1.f, -1.f, 1.f, 1.f, + -1.f, 1.f, 0.f, 0.f, + 1.f, 1.f, 1.f, 0.f }; if (!s_fullscreenQuadBuffer.Fill(vertices, 0, 4)) From 9efed23cbca3597fa7a8c0070ab8f7d3f0b0f0e7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Apr 2016 12:47:28 +0200 Subject: [PATCH 215/229] Utility/Algorithm: Fixes sphere generation Former-commit-id: 06f96d54f39b77929d9427c714d43202269df67a --- src/Nazara/Utility/AlgorithmUtility.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index 0b674c248..b23542993 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -104,8 +104,11 @@ namespace Nz // Et maintenant on affine la sphère for (unsigned int i = 0; i < recursionLevel; ++i) { - for (Vector3ui& triangle : triangles) + std::size_t triangleCount = triangles.size(); + for (std::size_t i = 0; i < triangleCount; ++i) { + Vector3ui& triangle = triangles[i]; + unsigned int a = GetMiddleVertex(triangle.x, triangle.y); unsigned int b = GetMiddleVertex(triangle.y, triangle.z); unsigned int c = GetMiddleVertex(triangle.z, triangle.x); From a31a9694094b87020bcabccb7dd44f7b2526b070 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Apr 2016 04:20:18 +0200 Subject: [PATCH 216/229] Replace useless reinterpret_cast by static_cast Former-commit-id: f61d644d968d4fe9523a5cd122e11525a9c2765d --- include/Nazara/Core/Endianness.inl | 2 +- include/Nazara/Core/SparsePtr.inl | 2 +- src/Nazara/Core/Error.cpp | 12 +++++----- src/Nazara/Core/MemoryManager.cpp | 4 ++-- src/Nazara/Core/MemoryView.cpp | 4 ++-- src/Nazara/Core/Win32/TaskSchedulerImpl.cpp | 2 +- .../Graphics/ForwardRenderTechnique.cpp | 4 ++-- src/Nazara/Lua/LuaInstance.cpp | 2 +- src/Nazara/Network/TcpClient.cpp | 2 +- src/Nazara/Network/Win32/SocketImpl.cpp | 2 +- src/Nazara/Renderer/DebugDrawer.cpp | 22 +++++++++---------- src/Nazara/Renderer/GpuQuery.cpp | 2 +- src/Nazara/Utility/Formats/MD2Loader.cpp | 4 ++-- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 2 +- src/Nazara/Utility/IndexMapper.cpp | 8 +++---- src/Nazara/Utility/Win32/InputImpl.cpp | 4 ++-- src/Nazara/Utility/Win32/WindowImpl.cpp | 6 ++--- 17 files changed, 42 insertions(+), 42 deletions(-) diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index 400224920..2949e3f19 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -34,7 +34,7 @@ namespace Nz inline void SwapBytes(void* buffer, unsigned int size) { - UInt8* bytes = reinterpret_cast(buffer); + UInt8* bytes = static_cast(buffer); unsigned int i = 0; unsigned int j = size - 1; diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index 166efe751..0da69b0ad 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -161,7 +161,7 @@ namespace Nz template void SparsePtr::SetPtr(VoidPtr ptr) { - m_ptr = reinterpret_cast(ptr); + m_ptr = static_cast(ptr); } /*! diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index ae6f0cc09..05dea1232 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -87,12 +87,12 @@ namespace Nz wchar_t* buffer = nullptr; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - code, - 0, - reinterpret_cast(&buffer), - 0, - nullptr); + nullptr, + code, + 0, + reinterpret_cast(&buffer), + 0, + nullptr); String error(String::Unicode(buffer)); LocalFree(buffer); diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index 5ee1755d7..3a4883bec 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -110,7 +110,7 @@ namespace Nz pthread_mutex_lock(&s_mutex); #endif - Block* ptr = reinterpret_cast(std::malloc(size+sizeof(Block))); + Block* ptr = static_cast(std::malloc(size+sizeof(Block))); if (!ptr) { char timeStr[23]; @@ -209,7 +209,7 @@ namespace Nz if (!pointer) return; - Block* ptr = reinterpret_cast(reinterpret_cast(pointer) - sizeof(Block)); + Block* ptr = reinterpret_cast(static_cast(pointer) - sizeof(Block)); if (ptr->magic != s_allocatedId) { char timeStr[23]; diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index 02c8b26c2..e501a031f 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -26,7 +26,7 @@ namespace Nz MemoryView::MemoryView(void* ptr, UInt64 size) : Stream(StreamOption_None, OpenMode_ReadWrite), - m_ptr(reinterpret_cast(ptr)), + m_ptr(static_cast(ptr)), m_pos(0), m_size(size) { @@ -43,7 +43,7 @@ namespace Nz MemoryView::MemoryView(const void* ptr, UInt64 size) : Stream(StreamOption_None, OpenMode_ReadOnly), - m_ptr(reinterpret_cast(const_cast(ptr))), //< Okay, right, const_cast is bad, but this pointer is still read-only + m_ptr(static_cast(const_cast(ptr))), //< Okay, right, const_cast is bad, but this pointer is still read-only m_pos(0), m_size(size) { diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index c93859d68..5b5d7153d 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -195,7 +195,7 @@ namespace Nz unsigned int __stdcall TaskSchedulerImpl::WorkerProc(void* userdata) { - unsigned int workerID = *reinterpret_cast(userdata); + unsigned int workerID = *static_cast(userdata); SetEvent(s_doneEvents[workerID]); Worker& worker = s_workers[workerID]; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 2db03b7f9..36f6918fa 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -272,7 +272,7 @@ namespace Nz { // On ouvre le buffer en écriture BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); - VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + VertexStruct_XYZ_Color_UV* vertices = static_cast(vertexMapper.GetPointer()); unsigned int spriteCount = 0; unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); @@ -411,7 +411,7 @@ namespace Nz billboardCount -= renderedBillboardCount; BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + BillboardPoint* vertices = static_cast(vertexMapper.GetPointer()); for (unsigned int i = 0; i < renderedBillboardCount; ++i) { diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index c6b6a45e5..8e437d759 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -633,7 +633,7 @@ namespace Nz void LuaInstance::PushFunction(LuaFunction func) const { - LuaFunction* luaFunc = reinterpret_cast(lua_newuserdata(m_state, sizeof(LuaFunction))); + LuaFunction* luaFunc = static_cast(lua_newuserdata(m_state, sizeof(LuaFunction))); PlacementNew(luaFunc, std::move(func)); lua_pushcclosure(m_state, ProxyFunc, 1); diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 5b31b6bd5..a134cf870 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -221,7 +221,7 @@ namespace Nz { int sendSize = static_cast(std::min(size - totalByteSent, std::numeric_limits::max())); //< Handle very large send int sentSize; - if (!SocketImpl::Send(m_handle, reinterpret_cast(buffer) + totalByteSent, sendSize, &sentSize, &m_lastError)) + if (!SocketImpl::Send(m_handle, static_cast(buffer) + totalByteSent, sendSize, &sentSize, &m_lastError)) { switch (m_lastError) { diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 1c5ee7ad0..35d4b2371 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -405,7 +405,7 @@ namespace Nz NazaraAssert(handle != InvalidHandle, "Invalid handle"); NazaraAssert(buffer && length > 0, "Invalid buffer"); - int byteRead = recv(handle, reinterpret_cast(buffer), length, 0); + int byteRead = recv(handle, static_cast(buffer), length, 0); if (byteRead == SOCKET_ERROR) { int errorCode = WSAGetLastError(); diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 03b8b63a8..5623e6e8d 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -67,7 +67,7 @@ namespace Nz } BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); - VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + VertexStruct_XYZ* vertex = static_cast(mapper.GetPointer()); Vector3f max, min; max = box.GetMaximum(); @@ -158,7 +158,7 @@ namespace Nz } BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); - VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + VertexStruct_XYZ* vertex = static_cast(mapper.GetPointer()); vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftBottom)); vertex++; @@ -240,7 +240,7 @@ namespace Nz } BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); - VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + VertexStruct_XYZ* vertex = static_cast(mapper.GetPointer()); vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftBottom)); vertex++; @@ -329,7 +329,7 @@ namespace Nz } BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, jointCount*2); - VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + VertexStruct_XYZ* vertex = static_cast(mapper.GetPointer()); unsigned int vertexCount = 0; for (unsigned int i = 0; i < jointCount; ++i) @@ -407,8 +407,8 @@ namespace Nz BufferMapper inputMapper(subMesh->GetVertexBuffer(), BufferAccess_ReadOnly); BufferMapper outputMapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, vertexCount); - MeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); - VertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); + MeshVertex* inputVertex = static_cast(inputMapper.GetPointer()); + VertexStruct_XYZ* outputVertex = static_cast(outputMapper.GetPointer()); for (unsigned int i = 0; i < normalCount; ++i) { @@ -449,7 +449,7 @@ namespace Nz transformMatrix.SetTranslation(origin); BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 16); - VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + VertexStruct_XYZ* vertex = static_cast(mapper.GetPointer()); // On calcule le reste des points Vector3f base(Vector3f::Forward()*length); @@ -575,8 +575,8 @@ namespace Nz BufferMapper inputMapper(subMesh->GetVertexBuffer(), BufferAccess_ReadOnly); BufferMapper outputMapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, vertexCount); - MeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); - VertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); + MeshVertex* inputVertex = static_cast(inputMapper.GetPointer()); + VertexStruct_XYZ* outputVertex = static_cast(outputMapper.GetPointer()); for (unsigned int i = 0; i < normalCount; ++i) { @@ -622,8 +622,8 @@ namespace Nz BufferMapper inputMapper(subMesh->GetVertexBuffer(), BufferAccess_ReadOnly); BufferMapper outputMapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, vertexCount); - MeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); - VertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); + MeshVertex* inputVertex = static_cast(inputMapper.GetPointer()); + VertexStruct_XYZ* outputVertex = static_cast(outputMapper.GetPointer()); for (unsigned int i = 0; i < tangentCount; ++i) { diff --git a/src/Nazara/Renderer/GpuQuery.cpp b/src/Nazara/Renderer/GpuQuery.cpp index 6c3d404ce..4e7ff228f 100644 --- a/src/Nazara/Renderer/GpuQuery.cpp +++ b/src/Nazara/Renderer/GpuQuery.cpp @@ -19,7 +19,7 @@ namespace Nz Context::EnsureContext(); m_id = 0; - glGenQueries(1, reinterpret_cast(&m_id)); + glGenQueries(1, static_cast(&m_id)); #ifdef NAZARA_DEBUG if (!m_id) diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 856a73823..184adfe17 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -115,7 +115,7 @@ namespace Nz stream.Read(&triangles[0], header.num_tris*sizeof(MD2_Triangle)); BufferMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); - UInt16* index = reinterpret_cast(indexMapper.GetPointer()); + UInt16* index = static_cast(indexMapper.GetPointer()); for (unsigned int i = 0; i < header.num_tris; ++i) { @@ -190,7 +190,7 @@ namespace Nz translate *= s; BufferMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); - MeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); + MeshVertex* vertex = static_cast(vertexMapper.GetPointer()); /// Chargement des coordonnées de texture const unsigned int indexFix[3] = {0, 2, 1}; // Pour respécifier les indices dans le bon ordre diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 4c4b61bae..629452161 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -249,7 +249,7 @@ namespace Nz VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage); BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); - MeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); + MeshVertex* vertex = static_cast(vertexMapper.GetPointer()); for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) { // Skinning MD5 (Formule d'Id Tech) diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index e95f9b3cd..adf80a764 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -14,25 +14,25 @@ namespace Nz { UInt32 Getter16(const void* buffer, unsigned int i) { - const UInt16* ptr = reinterpret_cast(buffer); + const UInt16* ptr = static_cast(buffer); return ptr[i]; } UInt32 Getter32(const void* buffer, unsigned int i) { - const UInt32* ptr = reinterpret_cast(buffer); + const UInt32* ptr = static_cast(buffer); return ptr[i]; } void Setter16(void* buffer, unsigned int i, UInt32 value) { - UInt16* ptr = reinterpret_cast(buffer); + UInt16* ptr = static_cast(buffer); ptr[i] = static_cast(value); } void Setter32(void* buffer, unsigned int i, UInt32 value) { - UInt32* ptr = reinterpret_cast(buffer); + UInt32* ptr = static_cast(buffer); ptr[i] = value; } diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Utility/Win32/InputImpl.cpp index 443e38855..ba604deb8 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Utility/Win32/InputImpl.cpp @@ -213,7 +213,7 @@ namespace Nz Vector2i EventImpl::GetMousePosition(const Window& relativeTo) { - HWND handle = reinterpret_cast(relativeTo.GetHandle()); + HWND handle = static_cast(relativeTo.GetHandle()); if (handle) { POINT pos; @@ -283,7 +283,7 @@ namespace Nz void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo) { - HWND handle = reinterpret_cast(relativeTo.GetHandle()); + HWND handle = static_cast(relativeTo.GetHandle()); if (handle) { POINT pos = {x, y}; diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index e910e8acc..2bf9c9d02 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -193,7 +193,7 @@ namespace Nz bool WindowImpl::Create(WindowHandle handle) { - m_handle = reinterpret_cast(handle); + m_handle = static_cast(handle); if (!m_handle || !IsWindow(m_handle)) { @@ -342,7 +342,7 @@ namespace Nz #endif if (cursor != WindowCursor_None) - m_cursor = reinterpret_cast(LoadImage(nullptr, windowsCursors[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED)); + m_cursor = static_cast(LoadImage(nullptr, windowsCursors[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED)); else m_cursor = nullptr; @@ -1125,7 +1125,7 @@ namespace Nz WindowImpl* me; if (message == WM_CREATE) { - me = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + me = static_cast(reinterpret_cast(lParam)->lpCreateParams); SetWindowLongPtr(window, GWL_USERDATA, reinterpret_cast(me)); } else From 59ef4bc9b54eea7be3a3954d3f53a119d7783a20 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Apr 2016 04:20:37 +0200 Subject: [PATCH 217/229] Core/UnitTests: Fix compilation Former-commit-id: 2d3581675f3e9144beb5abc7ec9fa714d021eb14 --- tests/Engine/Core/Serialization.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Engine/Core/Serialization.cpp b/tests/Engine/Core/Serialization.cpp index 299b9cc8f..a4d8ff75e 100644 --- a/tests/Engine/Core/Serialization.cpp +++ b/tests/Engine/Core/Serialization.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include From 1ec8c8c5e02d38206b3930a16fe7f68db1bb8857 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 11 Apr 2016 13:01:17 +0200 Subject: [PATCH 218/229] Core/Error: Remove Directory include in Error.hpp Former-commit-id: 61ed7168229dde265159fa5acde0c57c315b85fe --- include/Nazara/Core/Error.hpp | 11 +++++------ src/Nazara/Core/Error.cpp | 15 +++++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index b71bc8cf3..fbc4de38b 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -8,20 +8,19 @@ #define NAZARA_ERROR_HPP #include -#include #include -#include +#include #include #if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG) - #define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) + #define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, __FILE__, NAZARA_FUNCTION) #else #define NazaraAssert(a, err) for (;;) break #endif -#define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -#define NazaraInternalError(err) Nz::Error::Trigger(Nz::ErrorType_Internal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -#define NazaraWarning(err) Nz::Error::Trigger(Nz::ErrorType_Warning, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, __FILE__, NAZARA_FUNCTION) +#define NazaraInternalError(err) Nz::Error::Trigger(Nz::ErrorType_Internal, err, __LINE__, __FILE__, NAZARA_FUNCTION) +#define NazaraWarning(err) Nz::Error::Trigger(Nz::ErrorType_Warning, err, __LINE__, __FILE__, NAZARA_FUNCTION) namespace Nz { diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index 05dea1232..8de5e5747 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -87,12 +88,12 @@ namespace Nz wchar_t* buffer = nullptr; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - code, - 0, - reinterpret_cast(&buffer), - 0, - nullptr); + nullptr, + code, + 0, + reinterpret_cast(&buffer), + 0, + nullptr); String error(String::Unicode(buffer)); LocalFree(buffer); @@ -165,6 +166,8 @@ namespace Nz void Error::Trigger(ErrorType type, const String& error, unsigned int line, const char* file, const char* function) { + file = Nz::Directory::GetCurrentFileRelativeToEngine(file); + if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0) Log::WriteError(type, error, line, file, function); From 104e393d65891577957b8ed7ad67b726ed25c0cd Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 16 Apr 2016 18:38:52 +0200 Subject: [PATCH 219/229] Core/LockGuard: Improve LockGuard Former-commit-id: e9313d81c8cd9cb2cefef64a7c54713062ad9d6a --- include/Nazara/Core/LockGuard.hpp | 13 +++-- include/Nazara/Core/LockGuard.inl | 83 +++++++++++++++++++++++++++++++ src/Nazara/Core/LockGuard.cpp | 37 -------------- 3 files changed, 93 insertions(+), 40 deletions(-) create mode 100644 include/Nazara/Core/LockGuard.inl delete mode 100644 src/Nazara/Core/LockGuard.cpp diff --git a/include/Nazara/Core/LockGuard.hpp b/include/Nazara/Core/LockGuard.hpp index 2dac4b578..d9ef5aa85 100644 --- a/include/Nazara/Core/LockGuard.hpp +++ b/include/Nazara/Core/LockGuard.hpp @@ -13,15 +13,22 @@ namespace Nz { class Mutex; - class NAZARA_CORE_API LockGuard + class LockGuard { public: - LockGuard(Mutex& mutex); - ~LockGuard(); + inline LockGuard(Mutex& mutex, bool lock = true); + inline ~LockGuard(); + + inline void Lock(); + inline bool TryLock(); + inline void Unlock(); private: Mutex& m_mutex; + bool m_locked; }; } +#include + #endif // NAZARA_LOCKGUARD_HPP diff --git a/include/Nazara/Core/LockGuard.inl b/include/Nazara/Core/LockGuard.inl new file mode 100644 index 000000000..73beab112 --- /dev/null +++ b/include/Nazara/Core/LockGuard.inl @@ -0,0 +1,83 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + /*! + * \ingroup core + * \class Nz::LockGuard + * \brief Core class that represents a mutex wrapper that provides a convenient RAII-style mechanism + */ + + /*! + * \brief Constructs a LockGuard object with a mutex + * + * \param mutex Mutex to lock + * \param lock Should the mutex be locked by the constructor + */ + inline LockGuard::LockGuard(Mutex& mutex, bool lock) : + m_mutex(mutex), + m_locked(false) + { + if (lock) + { + m_mutex.Lock(); + m_locked = true; + } + } + + /*! + * \brief Destructs a LockGuard object and unlocks the mutex if it was previously locked + */ + inline LockGuard::~LockGuard() + { + if (m_locked) + m_mutex.Unlock(); + } + + /*! + * \brief Locks the underlying mutex + * + * \see Mutex::Lock + */ + inline void LockGuard::Lock() + { + NazaraAssert(!m_locked, "Mutex is already locked"); + + m_mutex.Lock(); + } + + /*! + * \brief Tries to lock the underlying mutex + * + * \see Mutex::TryLock + * + * \return true if the lock was acquired successfully + */ + inline bool LockGuard::TryLock() + { + NazaraAssert(!m_locked, "Mutex is already locked"); + + return m_mutex.TryLock(); + } + + /*! + * \brief Unlocks the underlying mutex + * + * \see Mutex::Unlock + */ + inline void LockGuard::Unlock() + { + NazaraAssert(m_locked, "Mutex is not locked"); + + m_mutex.Unlock(); + } +} + +#include diff --git a/src/Nazara/Core/LockGuard.cpp b/src/Nazara/Core/LockGuard.cpp deleted file mode 100644 index e714f05f7..000000000 --- a/src/Nazara/Core/LockGuard.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include - -namespace Nz -{ - /*! - * \ingroup core - * \class Nz::LockGuard - * \brief Core class that represents a mutex wrapper that provides a convenient RAII-style mechanism - */ - - /*! - * \brief Constructs a LockGuard object with a mutex - * - * \param mutex Mutex to lock - */ - - LockGuard::LockGuard(Mutex& mutex) : - m_mutex(mutex) - { - m_mutex.Lock(); - } - - /*! - * \brief Destructs a LockGuard object and unlocks the mutex - */ - - LockGuard::~LockGuard() - { - m_mutex.Unlock(); - } -} From c8dd28f75cc899364608332c9e81dd92edcee12c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 16 Apr 2016 18:40:58 +0200 Subject: [PATCH 220/229] Sdk/RenderSystem: Allow to change render technique Former-commit-id: ec61a2ebff138300344e6068917f0863c3d11859 --- SDK/include/NDK/Systems/RenderSystem.hpp | 8 ++++++-- SDK/include/NDK/Systems/RenderSystem.inl | 16 ++++++++++++++++ SDK/src/NDK/Systems/RenderSystem.cpp | 6 ++++-- .../Nazara/Graphics/AbstractRenderTechnique.hpp | 1 + .../Nazara/Graphics/DeferredRenderTechnique.hpp | 1 + .../Nazara/Graphics/ForwardRenderTechnique.hpp | 1 + src/Nazara/Graphics/DeferredRenderTechnique.cpp | 7 ++++++- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 13 ++++++++----- 8 files changed, 43 insertions(+), 10 deletions(-) diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index ff077278d..4b65de11d 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -8,7 +8,7 @@ #define NDK_SYSTEMS_RENDERSYSTEM_HPP #include -#include +#include #include #include #include @@ -25,11 +25,15 @@ namespace Ndk inline RenderSystem(const RenderSystem& renderSystem); ~RenderSystem() = default; + template void ChangeRenderTechnique(); + inline void ChangeRenderTechnique(std::unique_ptr&& renderTechnique); + inline const Nz::BackgroundRef& GetDefaultBackground() const; inline const Nz::Matrix4f& GetCoordinateSystemMatrix() const; inline Nz::Vector3f GetGlobalForward() const; inline Nz::Vector3f GetGlobalRight() const; inline Nz::Vector3f GetGlobalUp() const; + inline Nz::AbstractRenderTechnique& GetRenderTechnique() const; inline void SetDefaultBackground(Nz::BackgroundRef background); inline void SetGlobalForward(const Nz::Vector3f& direction); @@ -45,11 +49,11 @@ namespace Ndk void OnEntityValidation(Entity* entity, bool justAdded) override; void OnUpdate(float elapsedTime) override; + std::unique_ptr m_renderTechnique; EntityList m_cameras; EntityList m_drawables; EntityList m_lights; Nz::BackgroundRef m_background; - Nz::ForwardRenderTechnique m_renderTechnique; Nz::Matrix4f m_coordinateSystemMatrix; bool m_coordinateSystemInvalidated; }; diff --git a/SDK/include/NDK/Systems/RenderSystem.inl b/SDK/include/NDK/Systems/RenderSystem.inl index d0cb0af47..b85ace59f 100644 --- a/SDK/include/NDK/Systems/RenderSystem.inl +++ b/SDK/include/NDK/Systems/RenderSystem.inl @@ -9,6 +9,17 @@ namespace Ndk { } + template + inline void RenderSystem::ChangeRenderTechnique() + { + ChangeRenderTechnique(std::make_unique()); + } + + inline void RenderSystem::ChangeRenderTechnique(std::unique_ptr&& renderTechnique) + { + m_renderTechnique = std::move(renderTechnique); + } + inline const Nz::BackgroundRef& RenderSystem::GetDefaultBackground() const { return m_background; @@ -34,6 +45,11 @@ namespace Ndk return Nz::Vector3f(m_coordinateSystemMatrix.m12, m_coordinateSystemMatrix.m22, m_coordinateSystemMatrix.m32); } + inline Nz::AbstractRenderTechnique& RenderSystem::GetRenderTechnique() const + { + return *m_renderTechnique.get(); + } + inline void RenderSystem::SetDefaultBackground(Nz::BackgroundRef background) { m_background = std::move(background); diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 7d7956a12..3237bbe52 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -15,6 +15,7 @@ namespace Ndk m_coordinateSystemMatrix(Nz::Matrix4f::Identity()), m_coordinateSystemInvalidated(true) { + ChangeRenderTechnique(); SetDefaultBackground(Nz::ColorBackground::New()); SetUpdateRate(0.f); } @@ -73,7 +74,7 @@ namespace Ndk CameraComponent& camComponent = camera->GetComponent(); camComponent.ApplyView(); - Nz::AbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); + Nz::AbstractRenderQueue* renderQueue = m_renderTechnique->GetRenderQueue(); renderQueue->Clear(); //TODO: Culling @@ -99,7 +100,8 @@ namespace Ndk sceneData.background = m_background; sceneData.viewer = &camComponent; - m_renderTechnique.Draw(sceneData); + m_renderTechnique->Clear(sceneData); + m_renderTechnique->Draw(sceneData); } } diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index 5f268275e..d13ac88ee 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -28,6 +28,7 @@ namespace Nz AbstractRenderTechnique(AbstractRenderTechnique&&) = default; virtual ~AbstractRenderTechnique(); + virtual void Clear(const SceneData& sceneData) const = 0; virtual bool Draw(const SceneData& sceneData) const = 0; virtual void EnableInstancing(bool instancing); diff --git a/include/Nazara/Graphics/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp index 5d371b94f..99d1fc813 100644 --- a/include/Nazara/Graphics/DeferredRenderTechnique.hpp +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -32,6 +32,7 @@ namespace Nz DeferredRenderTechnique(); ~DeferredRenderTechnique(); + void Clear(const SceneData& sceneData) const override; bool Draw(const SceneData& sceneData) const override; void EnablePass(RenderPassType renderPass, int position, bool enable); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 920a6c0bd..6881ac2d7 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -24,6 +24,7 @@ namespace Nz ForwardRenderTechnique(); ~ForwardRenderTechnique() = default; + void Clear(const SceneData& sceneData) const override; bool Draw(const SceneData& sceneData) const override; unsigned int GetMaxLightPassPerObject() const; diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index 63342363c..88335d92b 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -120,7 +120,7 @@ namespace Nz for (unsigned int i = 0; i < 3; ++i) m_GBuffer[i] = Texture::New(); - + try { ErrorFlags errFlags(ErrorFlag_ThrowException); @@ -204,6 +204,11 @@ namespace Nz DeferredRenderTechnique::~DeferredRenderTechnique() = default; + void DeferredRenderTechnique::Clear(const SceneData& sceneData) const + { + NazaraUnused(sceneData); + } + bool DeferredRenderTechnique::Draw(const SceneData& sceneData) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 36f6918fa..21423fdc8 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -49,18 +49,21 @@ namespace Nz m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); } - bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const + void ForwardRenderTechnique::Clear(const SceneData& sceneData) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - m_renderQueue.Sort(sceneData.viewer); - Renderer::Enable(RendererParameter_DepthBuffer, true); Renderer::Enable(RendererParameter_DepthWrite, true); Renderer::Clear(RendererBuffer_Depth); if (sceneData.background) sceneData.background->Draw(sceneData.viewer); + } + + bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + m_renderQueue.Sort(sceneData.viewer); for (auto& pair : m_renderQueue.layers) { From 9ea9137c2111e388f8463c582061eb6ef9704c7b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 16 Apr 2016 18:48:27 +0200 Subject: [PATCH 221/229] Lua/LuaClass: Rename Set[Static]Method to Bind[Static]Method Former-commit-id: fee2269cb12a621443715946602827cbfc5efc42 --- SDK/src/NDK/LuaBinding_Audio.cpp | 106 ++++++++++----------- SDK/src/NDK/LuaBinding_Core.cpp | 142 ++++++++++++++-------------- SDK/src/NDK/LuaBinding_Graphics.cpp | 16 ++-- SDK/src/NDK/LuaBinding_Math.cpp | 8 +- SDK/src/NDK/LuaBinding_Network.cpp | 30 +++--- SDK/src/NDK/LuaBinding_SDK.cpp | 62 ++++++------ SDK/src/NDK/LuaBinding_Utility.cpp | 106 ++++++++++----------- include/Nazara/Lua/LuaClass.hpp | 16 ++-- include/Nazara/Lua/LuaClass.inl | 24 ++--- 9 files changed, 256 insertions(+), 254 deletions(-) diff --git a/SDK/src/NDK/LuaBinding_Audio.cpp b/SDK/src/NDK/LuaBinding_Audio.cpp index 542c6b716..7c204b833 100644 --- a/SDK/src/NDK/LuaBinding_Audio.cpp +++ b/SDK/src/NDK/LuaBinding_Audio.cpp @@ -18,28 +18,28 @@ namespace Ndk //musicClass.SetMethod("Create", &Nz::Music::Create); //musicClass.SetMethod("Destroy", &Nz::Music::Destroy); - musicClass.SetMethod("EnableLooping", &Nz::Music::EnableLooping); + musicClass.BindMethod("EnableLooping", &Nz::Music::EnableLooping); - musicClass.SetMethod("GetDuration", &Nz::Music::GetDuration); - musicClass.SetMethod("GetFormat", &Nz::Music::GetFormat); - musicClass.SetMethod("GetPlayingOffset", &Nz::Music::GetPlayingOffset); - musicClass.SetMethod("GetSampleCount", &Nz::Music::GetSampleCount); - musicClass.SetMethod("GetSampleRate", &Nz::Music::GetSampleRate); - musicClass.SetMethod("GetStatus", &Nz::Music::GetStatus); + musicClass.BindMethod("GetDuration", &Nz::Music::GetDuration); + musicClass.BindMethod("GetFormat", &Nz::Music::GetFormat); + musicClass.BindMethod("GetPlayingOffset", &Nz::Music::GetPlayingOffset); + musicClass.BindMethod("GetSampleCount", &Nz::Music::GetSampleCount); + musicClass.BindMethod("GetSampleRate", &Nz::Music::GetSampleRate); + musicClass.BindMethod("GetStatus", &Nz::Music::GetStatus); - musicClass.SetMethod("IsLooping", &Nz::Music::IsLooping); + musicClass.BindMethod("IsLooping", &Nz::Music::IsLooping); - musicClass.SetMethod("OpenFromFile", &Nz::Music::OpenFromFile, Nz::MusicParams()); + musicClass.BindMethod("OpenFromFile", &Nz::Music::OpenFromFile, Nz::MusicParams()); - musicClass.SetMethod("Pause", &Nz::Music::Pause); - musicClass.SetMethod("Play", &Nz::Music::Play); + musicClass.BindMethod("Pause", &Nz::Music::Pause); + musicClass.BindMethod("Play", &Nz::Music::Play); - musicClass.SetMethod("SetPlayingOffset", &Nz::Music::SetPlayingOffset); + musicClass.BindMethod("SetPlayingOffset", &Nz::Music::SetPlayingOffset); - musicClass.SetMethod("Stop", &Nz::Music::Stop); + musicClass.BindMethod("Stop", &Nz::Music::Stop); // Manual - musicClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Music& music) -> int + musicClass.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Music& music) -> int { Nz::StringStream stream("Music("); stream << music.GetFilePath() << ')'; @@ -56,17 +56,17 @@ namespace Ndk return new Nz::Sound; }); - soundClass.SetMethod("GetBuffer", &Nz::Sound::GetBuffer); + soundClass.BindMethod("GetBuffer", &Nz::Sound::GetBuffer); - soundClass.SetMethod("IsPlayable", &Nz::Sound::IsPlayable); - soundClass.SetMethod("IsPlaying", &Nz::Sound::IsPlaying); + soundClass.BindMethod("IsPlayable", &Nz::Sound::IsPlayable); + soundClass.BindMethod("IsPlaying", &Nz::Sound::IsPlaying); - soundClass.SetMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); + soundClass.BindMethod("LoadFromFile", &Nz::Sound::LoadFromFile, Nz::SoundBufferParams()); - soundClass.SetMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); + soundClass.BindMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); // Manual - soundClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int + soundClass.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& sound) -> int { Nz::StringStream stream("Sound("); if (const Nz::SoundBuffer* buffer = sound.GetBuffer()) @@ -84,21 +84,21 @@ namespace Ndk return new Nz::SoundBufferRef(new Nz::SoundBuffer); }); - soundBuffer.SetMethod("Destroy", &Nz::SoundBuffer::Destroy); + soundBuffer.BindMethod("Destroy", &Nz::SoundBuffer::Destroy); - soundBuffer.SetMethod("GetDuration", &Nz::SoundBuffer::GetDuration); - soundBuffer.SetMethod("GetFormat", &Nz::SoundBuffer::GetFormat); - soundBuffer.SetMethod("GetSampleCount", &Nz::SoundBuffer::GetSampleCount); - soundBuffer.SetMethod("GetSampleRate", &Nz::SoundBuffer::GetSampleRate); + soundBuffer.BindMethod("GetDuration", &Nz::SoundBuffer::GetDuration); + soundBuffer.BindMethod("GetFormat", &Nz::SoundBuffer::GetFormat); + soundBuffer.BindMethod("GetSampleCount", &Nz::SoundBuffer::GetSampleCount); + soundBuffer.BindMethod("GetSampleRate", &Nz::SoundBuffer::GetSampleRate); - soundBuffer.SetMethod("IsValid", &Nz::SoundBuffer::IsValid); + soundBuffer.BindMethod("IsValid", &Nz::SoundBuffer::IsValid); - soundBuffer.SetMethod("LoadFromFile", &Nz::SoundBuffer::LoadFromFile, Nz::SoundBufferParams()); + soundBuffer.BindMethod("LoadFromFile", &Nz::SoundBuffer::LoadFromFile, Nz::SoundBufferParams()); - soundBuffer.SetStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported); + soundBuffer.BindStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported); // Manual - soundBuffer.SetMethod("Create", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int + soundBuffer.BindMethod("Create", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int { int index = 1; Nz::AudioFormat format = lua.Check(&index); @@ -113,13 +113,13 @@ namespace Ndk return 1; }); - soundBuffer.SetMethod("GetSamples", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int + soundBuffer.BindMethod("GetSamples", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int { lua.PushString(reinterpret_cast(instance->GetSamples()), instance->GetSampleCount() * sizeof(Nz::Int16)); return 1; }); - soundBuffer.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int + soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int { Nz::StringStream stream("SoundBuffer("); if (soundBuffer->IsValid()) @@ -137,33 +137,33 @@ namespace Ndk }); /*********************************** Nz::SoundEmitter **********************************/ - soundEmitter.SetMethod("EnableLooping", &Nz::SoundEmitter::EnableLooping); - soundEmitter.SetMethod("EnableSpatialization", &Nz::SoundEmitter::EnableSpatialization); + soundEmitter.BindMethod("EnableLooping", &Nz::SoundEmitter::EnableLooping); + soundEmitter.BindMethod("EnableSpatialization", &Nz::SoundEmitter::EnableSpatialization); - soundEmitter.SetMethod("GetAttenuation", &Nz::SoundEmitter::GetAttenuation); - soundEmitter.SetMethod("GetDuration", &Nz::SoundEmitter::GetDuration); - soundEmitter.SetMethod("GetMinDistance", &Nz::SoundEmitter::GetMinDistance); - soundEmitter.SetMethod("GetPitch", &Nz::SoundEmitter::GetPitch); - soundEmitter.SetMethod("GetPlayingOffset", &Nz::SoundEmitter::GetPlayingOffset); - soundEmitter.SetMethod("GetPosition", &Nz::Sound::GetPosition); - soundEmitter.SetMethod("GetStatus", &Nz::SoundEmitter::GetStatus); - soundEmitter.SetMethod("GetVelocity", &Nz::Sound::GetVelocity); - soundEmitter.SetMethod("GetVolume", &Nz::SoundEmitter::GetVolume); + soundEmitter.BindMethod("GetAttenuation", &Nz::SoundEmitter::GetAttenuation); + soundEmitter.BindMethod("GetDuration", &Nz::SoundEmitter::GetDuration); + soundEmitter.BindMethod("GetMinDistance", &Nz::SoundEmitter::GetMinDistance); + soundEmitter.BindMethod("GetPitch", &Nz::SoundEmitter::GetPitch); + soundEmitter.BindMethod("GetPlayingOffset", &Nz::SoundEmitter::GetPlayingOffset); + soundEmitter.BindMethod("GetPosition", &Nz::Sound::GetPosition); + soundEmitter.BindMethod("GetStatus", &Nz::SoundEmitter::GetStatus); + soundEmitter.BindMethod("GetVelocity", &Nz::Sound::GetVelocity); + soundEmitter.BindMethod("GetVolume", &Nz::SoundEmitter::GetVolume); - soundEmitter.SetMethod("IsLooping", &Nz::SoundEmitter::IsLooping); - soundEmitter.SetMethod("IsSpatialized", &Nz::SoundEmitter::IsSpatialized); + soundEmitter.BindMethod("IsLooping", &Nz::SoundEmitter::IsLooping); + soundEmitter.BindMethod("IsSpatialized", &Nz::SoundEmitter::IsSpatialized); - soundEmitter.SetMethod("Pause", &Nz::SoundEmitter::Pause); - soundEmitter.SetMethod("Play", &Nz::SoundEmitter::Play); + soundEmitter.BindMethod("Pause", &Nz::SoundEmitter::Pause); + soundEmitter.BindMethod("Play", &Nz::SoundEmitter::Play); - soundEmitter.SetMethod("SetAttenuation", &Nz::SoundEmitter::SetAttenuation); - soundEmitter.SetMethod("SetMinDistance", &Nz::SoundEmitter::SetMinDistance); - soundEmitter.SetMethod("SetPitch", &Nz::SoundEmitter::SetPitch); - soundEmitter.SetMethod("SetPosition", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetPosition); - soundEmitter.SetMethod("SetVelocity", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetVelocity); - soundEmitter.SetMethod("SetVolume", &Nz::SoundEmitter::SetVolume); + soundEmitter.BindMethod("SetAttenuation", &Nz::SoundEmitter::SetAttenuation); + soundEmitter.BindMethod("SetMinDistance", &Nz::SoundEmitter::SetMinDistance); + soundEmitter.BindMethod("SetPitch", &Nz::SoundEmitter::SetPitch); + soundEmitter.BindMethod("SetPosition", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetPosition); + soundEmitter.BindMethod("SetVelocity", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetVelocity); + soundEmitter.BindMethod("SetVolume", &Nz::SoundEmitter::SetVolume); - soundEmitter.SetMethod("Stop", &Nz::SoundEmitter::Stop); + soundEmitter.BindMethod("Stop", &Nz::SoundEmitter::Stop); } void LuaBinding::RegisterAudio(Nz::LuaInstance& instance) diff --git a/SDK/src/NDK/LuaBinding_Core.cpp b/SDK/src/NDK/LuaBinding_Core.cpp index 8ed8682ce..a4676284e 100644 --- a/SDK/src/NDK/LuaBinding_Core.cpp +++ b/SDK/src/NDK/LuaBinding_Core.cpp @@ -14,16 +14,16 @@ namespace Ndk return new Nz::Clock(lua.Check(&argIndex, 0), lua.Check(&argIndex, false)); }); - clockClass.SetMethod("GetMicroseconds", &Nz::Clock::GetMicroseconds); - clockClass.SetMethod("GetMilliseconds", &Nz::Clock::GetMilliseconds); - clockClass.SetMethod("GetSeconds", &Nz::Clock::GetSeconds); - clockClass.SetMethod("IsPaused", &Nz::Clock::IsPaused); - clockClass.SetMethod("Pause", &Nz::Clock::Pause); - clockClass.SetMethod("Restart", &Nz::Clock::Restart); - clockClass.SetMethod("Unpause", &Nz::Clock::Unpause); + clockClass.BindMethod("GetMicroseconds", &Nz::Clock::GetMicroseconds); + clockClass.BindMethod("GetMilliseconds", &Nz::Clock::GetMilliseconds); + clockClass.BindMethod("GetSeconds", &Nz::Clock::GetSeconds); + clockClass.BindMethod("IsPaused", &Nz::Clock::IsPaused); + clockClass.BindMethod("Pause", &Nz::Clock::Pause); + clockClass.BindMethod("Restart", &Nz::Clock::Restart); + clockClass.BindMethod("Unpause", &Nz::Clock::Unpause); // Manual - clockClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& clock) -> int { + clockClass.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& clock) -> int { Nz::StringStream stream("Clock(Elapsed: "); stream << clock.GetSeconds(); stream << "s, Paused: "; @@ -52,29 +52,29 @@ namespace Ndk return nullptr; }); - directoryClass.SetMethod("Close", &Nz::Directory::Close); - directoryClass.SetMethod("Exists", &Nz::Directory::Exists); - directoryClass.SetMethod("GetPath", &Nz::Directory::GetPath); - directoryClass.SetMethod("GetPattern", &Nz::Directory::GetPattern); - directoryClass.SetMethod("GetResultName", &Nz::Directory::GetResultName); - directoryClass.SetMethod("GetResultPath", &Nz::Directory::GetResultPath); - directoryClass.SetMethod("GetResultSize", &Nz::Directory::GetResultSize); - directoryClass.SetMethod("IsOpen", &Nz::Directory::IsOpen); - directoryClass.SetMethod("IsResultDirectory", &Nz::Directory::IsResultDirectory); - directoryClass.SetMethod("NextResult", &Nz::Directory::NextResult, true); - directoryClass.SetMethod("Open", &Nz::Directory::Open); - directoryClass.SetMethod("SetPath", &Nz::Directory::SetPath); - directoryClass.SetMethod("SetPattern", &Nz::Directory::SetPattern); + directoryClass.BindMethod("Close", &Nz::Directory::Close); + directoryClass.BindMethod("Exists", &Nz::Directory::Exists); + directoryClass.BindMethod("GetPath", &Nz::Directory::GetPath); + directoryClass.BindMethod("GetPattern", &Nz::Directory::GetPattern); + directoryClass.BindMethod("GetResultName", &Nz::Directory::GetResultName); + directoryClass.BindMethod("GetResultPath", &Nz::Directory::GetResultPath); + directoryClass.BindMethod("GetResultSize", &Nz::Directory::GetResultSize); + directoryClass.BindMethod("IsOpen", &Nz::Directory::IsOpen); + directoryClass.BindMethod("IsResultDirectory", &Nz::Directory::IsResultDirectory); + directoryClass.BindMethod("NextResult", &Nz::Directory::NextResult, true); + directoryClass.BindMethod("Open", &Nz::Directory::Open); + directoryClass.BindMethod("SetPath", &Nz::Directory::SetPath); + directoryClass.BindMethod("SetPattern", &Nz::Directory::SetPattern); - directoryClass.SetStaticMethod("Copy", Nz::Directory::Copy); - directoryClass.SetStaticMethod("Create", Nz::Directory::Create); - directoryClass.SetStaticMethod("Exists", Nz::Directory::Exists); - directoryClass.SetStaticMethod("GetCurrent", Nz::Directory::GetCurrent); - directoryClass.SetStaticMethod("Remove", Nz::Directory::Remove); - directoryClass.SetStaticMethod("SetCurrent", Nz::Directory::SetCurrent); + directoryClass.BindStaticMethod("Copy", Nz::Directory::Copy); + directoryClass.BindStaticMethod("Create", Nz::Directory::Create); + directoryClass.BindStaticMethod("Exists", Nz::Directory::Exists); + directoryClass.BindStaticMethod("GetCurrent", Nz::Directory::GetCurrent); + directoryClass.BindStaticMethod("Remove", Nz::Directory::Remove); + directoryClass.BindStaticMethod("SetCurrent", Nz::Directory::SetCurrent); // Manual - directoryClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Directory& directory) -> int { + directoryClass.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Directory& directory) -> int { Nz::StringStream stream("Directory("); stream << directory.GetPath(); stream << ')'; @@ -84,22 +84,22 @@ namespace Ndk }); /*********************************** Nz::Stream ***********************************/ - streamClass.SetMethod("EnableTextMode", &Nz::Stream::EnableTextMode); - streamClass.SetMethod("Flush", &Nz::Stream::Flush); - streamClass.SetMethod("GetCursorPos", &Nz::Stream::GetCursorPos); - streamClass.SetMethod("GetDirectory", &Nz::Stream::GetDirectory); - streamClass.SetMethod("GetPath", &Nz::Stream::GetPath); - streamClass.SetMethod("GetOpenMode", &Nz::Stream::GetOpenMode); - streamClass.SetMethod("GetStreamOptions", &Nz::Stream::GetStreamOptions); - streamClass.SetMethod("GetSize", &Nz::Stream::GetSize); - streamClass.SetMethod("ReadLine", &Nz::Stream::ReadLine, 0U); - streamClass.SetMethod("IsReadable", &Nz::Stream::IsReadable); - streamClass.SetMethod("IsSequential", &Nz::Stream::IsSequential); - streamClass.SetMethod("IsTextModeEnabled", &Nz::Stream::IsTextModeEnabled); - streamClass.SetMethod("IsWritable", &Nz::Stream::IsWritable); - streamClass.SetMethod("SetCursorPos", &Nz::Stream::SetCursorPos); + streamClass.BindMethod("EnableTextMode", &Nz::Stream::EnableTextMode); + streamClass.BindMethod("Flush", &Nz::Stream::Flush); + streamClass.BindMethod("GetCursorPos", &Nz::Stream::GetCursorPos); + streamClass.BindMethod("GetDirectory", &Nz::Stream::GetDirectory); + streamClass.BindMethod("GetPath", &Nz::Stream::GetPath); + streamClass.BindMethod("GetOpenMode", &Nz::Stream::GetOpenMode); + streamClass.BindMethod("GetStreamOptions", &Nz::Stream::GetStreamOptions); + streamClass.BindMethod("GetSize", &Nz::Stream::GetSize); + streamClass.BindMethod("ReadLine", &Nz::Stream::ReadLine, 0U); + streamClass.BindMethod("IsReadable", &Nz::Stream::IsReadable); + streamClass.BindMethod("IsSequential", &Nz::Stream::IsSequential); + streamClass.BindMethod("IsTextModeEnabled", &Nz::Stream::IsTextModeEnabled); + streamClass.BindMethod("IsWritable", &Nz::Stream::IsWritable); + streamClass.BindMethod("SetCursorPos", &Nz::Stream::SetCursorPos); - streamClass.SetMethod("Read", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { + streamClass.BindMethod("Read", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { int argIndex = 1; std::size_t length = lua.Check(&argIndex); @@ -111,7 +111,7 @@ namespace Ndk return 1; }); - streamClass.SetMethod("Write", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { + streamClass.BindMethod("Write", [] (Nz::LuaInstance& lua, Nz::Stream& stream) -> int { int argIndex = 1; std::size_t bufferSize = 0; @@ -147,37 +147,37 @@ namespace Ndk return nullptr; }); - fileClass.SetMethod("Close", &Nz::File::Close); - fileClass.SetMethod("Copy", &Nz::File::Copy); - fileClass.SetMethod("Delete", &Nz::File::Delete); - fileClass.SetMethod("EndOfFile", &Nz::File::EndOfFile); - fileClass.SetMethod("Exists", &Nz::File::Exists); - fileClass.SetMethod("GetCreationTime", &Nz::File::GetCreationTime); - fileClass.SetMethod("GetFileName", &Nz::File::GetFileName); - fileClass.SetMethod("GetLastAccessTime", &Nz::File::GetLastAccessTime); - fileClass.SetMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); - fileClass.SetMethod("IsOpen", &Nz::File::IsOpen); - fileClass.SetMethod("Rename", &Nz::File::GetLastWriteTime); - fileClass.SetMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); - fileClass.SetMethod("SetFile", &Nz::File::GetLastWriteTime); + fileClass.BindMethod("Close", &Nz::File::Close); + fileClass.BindMethod("Copy", &Nz::File::Copy); + fileClass.BindMethod("Delete", &Nz::File::Delete); + fileClass.BindMethod("EndOfFile", &Nz::File::EndOfFile); + fileClass.BindMethod("Exists", &Nz::File::Exists); + fileClass.BindMethod("GetCreationTime", &Nz::File::GetCreationTime); + fileClass.BindMethod("GetFileName", &Nz::File::GetFileName); + fileClass.BindMethod("GetLastAccessTime", &Nz::File::GetLastAccessTime); + fileClass.BindMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); + fileClass.BindMethod("IsOpen", &Nz::File::IsOpen); + fileClass.BindMethod("Rename", &Nz::File::GetLastWriteTime); + fileClass.BindMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); + fileClass.BindMethod("SetFile", &Nz::File::GetLastWriteTime); - fileClass.SetStaticMethod("AbsolutePath", &Nz::File::AbsolutePath); - fileClass.SetStaticMethod("ComputeHash", (Nz::ByteArray (*)(Nz::HashType, const Nz::String&)) &Nz::File::ComputeHash); - fileClass.SetStaticMethod("Copy", &Nz::File::Copy); - fileClass.SetStaticMethod("Delete", &Nz::File::Delete); - fileClass.SetStaticMethod("Exists", &Nz::File::Exists); + fileClass.BindStaticMethod("AbsolutePath", &Nz::File::AbsolutePath); + fileClass.BindStaticMethod("ComputeHash", (Nz::ByteArray (*)(Nz::HashType, const Nz::String&)) &Nz::File::ComputeHash); + fileClass.BindStaticMethod("Copy", &Nz::File::Copy); + fileClass.BindStaticMethod("Delete", &Nz::File::Delete); + fileClass.BindStaticMethod("Exists", &Nz::File::Exists); //fileClass.SetStaticMethod("GetCreationTime", &Nz::File::GetCreationTime); - fileClass.SetStaticMethod("GetDirectory", &Nz::File::GetDirectory); + fileClass.BindStaticMethod("GetDirectory", &Nz::File::GetDirectory); //fileClass.SetStaticMethod("GetLastAccessTime", &Nz::File::GetLastAccessTime); //fileClass.SetStaticMethod("GetLastWriteTime", &Nz::File::GetLastWriteTime); - fileClass.SetStaticMethod("GetSize", &Nz::File::GetSize); - fileClass.SetStaticMethod("IsAbsolute", &Nz::File::IsAbsolute); - fileClass.SetStaticMethod("NormalizePath", &Nz::File::NormalizePath); - fileClass.SetStaticMethod("NormalizeSeparators", &Nz::File::NormalizeSeparators); - fileClass.SetStaticMethod("Rename", &Nz::File::Rename); + fileClass.BindStaticMethod("GetSize", &Nz::File::GetSize); + fileClass.BindStaticMethod("IsAbsolute", &Nz::File::IsAbsolute); + fileClass.BindStaticMethod("NormalizePath", &Nz::File::NormalizePath); + fileClass.BindStaticMethod("NormalizeSeparators", &Nz::File::NormalizeSeparators); + fileClass.BindStaticMethod("Rename", &Nz::File::Rename); // Manual - fileClass.SetMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& file) -> int + fileClass.BindMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 2U); @@ -196,7 +196,7 @@ namespace Ndk return 0; }); - fileClass.SetMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& file) -> int + fileClass.BindMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 2U); @@ -214,7 +214,7 @@ namespace Ndk return 0; }); - fileClass.SetMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { + fileClass.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::File& file) -> int { Nz::StringStream stream("File("); if (file.IsOpen()) stream << "Path: " << file.GetPath(); diff --git a/SDK/src/NDK/LuaBinding_Graphics.cpp b/SDK/src/NDK/LuaBinding_Graphics.cpp index e3bbaec66..3d7597dd5 100644 --- a/SDK/src/NDK/LuaBinding_Graphics.cpp +++ b/SDK/src/NDK/LuaBinding_Graphics.cpp @@ -22,21 +22,21 @@ namespace Ndk }); //modelClass.SetMethod("GetMaterial", &Nz::Model::GetMaterial); - modelClass.SetMethod("GetMaterialCount", &Nz::Model::GetMaterialCount); + modelClass.BindMethod("GetMaterialCount", &Nz::Model::GetMaterialCount); //modelClass.SetMethod("GetMesh", &Nz::Model::GetMesh); - modelClass.SetMethod("GetSkin", &Nz::Model::GetSkin); - modelClass.SetMethod("GetSkinCount", &Nz::Model::GetSkinCount); + modelClass.BindMethod("GetSkin", &Nz::Model::GetSkin); + modelClass.BindMethod("GetSkinCount", &Nz::Model::GetSkinCount); - modelClass.SetMethod("IsAnimated", &Nz::Model::IsAnimated); - modelClass.SetMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); + modelClass.BindMethod("IsAnimated", &Nz::Model::IsAnimated); + modelClass.BindMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); - modelClass.SetMethod("Reset", &Nz::Model::Reset); + modelClass.BindMethod("Reset", &Nz::Model::Reset); //modelClass.SetMethod("SetMaterial", &Nz::Model::SetMaterial); //modelClass.SetMethod("SetMesh", &Nz::Model::SetMesh); //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); - modelClass.SetMethod("SetSkin", &Nz::Model::SetSkin); - modelClass.SetMethod("SetSkinCount", &Nz::Model::SetSkinCount); + modelClass.BindMethod("SetSkin", &Nz::Model::SetSkin); + modelClass.BindMethod("SetSkinCount", &Nz::Model::SetSkinCount); } void LuaBinding::RegisterGraphics(Nz::LuaInstance& instance) diff --git a/SDK/src/NDK/LuaBinding_Math.cpp b/SDK/src/NDK/LuaBinding_Math.cpp index 5d7bc5a6b..808c93f86 100644 --- a/SDK/src/NDK/LuaBinding_Math.cpp +++ b/SDK/src/NDK/LuaBinding_Math.cpp @@ -28,7 +28,7 @@ namespace Ndk return nullptr; }); - eulerAnglesClass.SetMethod("__tostring", &Nz::EulerAnglesd::ToString); + eulerAnglesClass.BindMethod("__tostring", &Nz::EulerAnglesd::ToString); eulerAnglesClass.SetGetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) { @@ -173,7 +173,7 @@ namespace Ndk return nullptr; }); - quaternionClass.SetMethod("__tostring", &Nz::Quaterniond::ToString); + quaternionClass.BindMethod("__tostring", &Nz::Quaterniond::ToString); quaternionClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) { @@ -262,7 +262,7 @@ namespace Ndk return nullptr; }); - vector2dClass.SetMethod("__tostring", &Nz::Vector2d::ToString); + vector2dClass.BindMethod("__tostring", &Nz::Vector2d::ToString); vector2dClass.SetGetter([](Nz::LuaInstance& lua, Nz::Vector2d& instance) { @@ -381,7 +381,7 @@ namespace Ndk return nullptr; }); - vector3dClass.SetMethod("__tostring", &Nz::Vector3d::ToString); + vector3dClass.BindMethod("__tostring", &Nz::Vector3d::ToString); vector3dClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) { diff --git a/SDK/src/NDK/LuaBinding_Network.cpp b/SDK/src/NDK/LuaBinding_Network.cpp index 14f0b12ca..4b8334017 100644 --- a/SDK/src/NDK/LuaBinding_Network.cpp +++ b/SDK/src/NDK/LuaBinding_Network.cpp @@ -8,13 +8,13 @@ namespace Ndk void LuaBinding::BindNetwork() { /*********************************** Nz::AbstractSocket **********************************/ - abstractSocketClass.SetMethod("Close", &Nz::AbstractSocket::Close); - abstractSocketClass.SetMethod("EnableBlocking", &Nz::AbstractSocket::EnableBlocking); - abstractSocketClass.SetMethod("GetLastError", &Nz::AbstractSocket::GetLastError); - abstractSocketClass.SetMethod("GetState", &Nz::AbstractSocket::GetState); - abstractSocketClass.SetMethod("GetType", &Nz::AbstractSocket::GetType); - abstractSocketClass.SetMethod("IsBlockingEnabled", &Nz::AbstractSocket::IsBlockingEnabled); - abstractSocketClass.SetMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes); + abstractSocketClass.BindMethod("Close", &Nz::AbstractSocket::Close); + abstractSocketClass.BindMethod("EnableBlocking", &Nz::AbstractSocket::EnableBlocking); + abstractSocketClass.BindMethod("GetLastError", &Nz::AbstractSocket::GetLastError); + abstractSocketClass.BindMethod("GetState", &Nz::AbstractSocket::GetState); + abstractSocketClass.BindMethod("GetType", &Nz::AbstractSocket::GetType); + abstractSocketClass.BindMethod("IsBlockingEnabled", &Nz::AbstractSocket::IsBlockingEnabled); + abstractSocketClass.BindMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes); /*********************************** Nz::IpAddress **********************************/ ipAddressClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::IpAddress* @@ -43,14 +43,14 @@ namespace Ndk return nullptr; }); - ipAddressClass.SetMethod("GetPort", &Nz::IpAddress::GetPort); - ipAddressClass.SetMethod("GetProtocol", &Nz::IpAddress::GetProtocol); - ipAddressClass.SetMethod("IsLoopback", &Nz::IpAddress::IsLoopback); - ipAddressClass.SetMethod("IsValid", &Nz::IpAddress::IsValid); - ipAddressClass.SetMethod("ToUInt32", &Nz::IpAddress::ToUInt32); - ipAddressClass.SetMethod("__tostring", &Nz::IpAddress::ToString); + ipAddressClass.BindMethod("GetPort", &Nz::IpAddress::GetPort); + ipAddressClass.BindMethod("GetProtocol", &Nz::IpAddress::GetProtocol); + ipAddressClass.BindMethod("IsLoopback", &Nz::IpAddress::IsLoopback); + ipAddressClass.BindMethod("IsValid", &Nz::IpAddress::IsValid); + ipAddressClass.BindMethod("ToUInt32", &Nz::IpAddress::ToUInt32); + ipAddressClass.BindMethod("__tostring", &Nz::IpAddress::ToString); - ipAddressClass.SetStaticMethod("ResolveAddress", [] (Nz::LuaInstance& instance) -> int + ipAddressClass.BindStaticMethod("ResolveAddress", [] (Nz::LuaInstance& instance) -> int { Nz::String service; Nz::ResolveError error = Nz::ResolveError_Unknown; @@ -72,7 +72,7 @@ namespace Ndk } }); - ipAddressClass.SetStaticMethod("ResolveHostname", [] (Nz::LuaInstance& instance) -> int + ipAddressClass.BindStaticMethod("ResolveHostname", [] (Nz::LuaInstance& instance) -> int { Nz::ResolveError error = Nz::ResolveError_Unknown; diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index 3d5088a7e..da456c732 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -49,14 +49,14 @@ namespace Ndk #ifndef NDK_SERVER //application.SetMethod("AddWindow", &Application::AddWindow); #endif - application.SetMethod("AddWorld", [] (Nz::LuaInstance& instance, Application* application) -> int + application.BindMethod("AddWorld", [] (Nz::LuaInstance& instance, Application* application) -> int { instance.Push(application->AddWorld().CreateHandle()); return 1; }); - application.SetMethod("GetUpdateTime", &Application::GetUpdateTime); - application.SetMethod("Quit", &Application::Quit); + application.BindMethod("GetUpdateTime", &Application::GetUpdateTime); + application.BindMethod("Quit", &Application::Quit); /*********************************** Ndk::Console **********************************/ #ifndef NDK_SERVER @@ -65,40 +65,40 @@ namespace Ndk return handle->GetObject(); }); - consoleClass.SetMethod("AddLine", &Console::AddLine, Nz::Color::White); - consoleClass.SetMethod("Clear", &Console::Clear); - consoleClass.SetMethod("GetCharacterSize", &Console::GetCharacterSize); - consoleClass.SetMethod("GetHistory", &Console::GetHistory); - consoleClass.SetMethod("GetHistoryBackground", &Console::GetHistoryBackground); - consoleClass.SetMethod("GetInput", &Console::GetInput); - consoleClass.SetMethod("GetInputBackground", &Console::GetInputBackground); - consoleClass.SetMethod("GetSize", &Console::GetSize); + consoleClass.BindMethod("AddLine", &Console::AddLine, Nz::Color::White); + consoleClass.BindMethod("Clear", &Console::Clear); + consoleClass.BindMethod("GetCharacterSize", &Console::GetCharacterSize); + consoleClass.BindMethod("GetHistory", &Console::GetHistory); + consoleClass.BindMethod("GetHistoryBackground", &Console::GetHistoryBackground); + consoleClass.BindMethod("GetInput", &Console::GetInput); + consoleClass.BindMethod("GetInputBackground", &Console::GetInputBackground); + consoleClass.BindMethod("GetSize", &Console::GetSize); //consoleClass.SetMethod("GetTextFont", &Console::GetTextFont); - consoleClass.SetMethod("IsVisible", &Console::IsVisible); + consoleClass.BindMethod("IsVisible", &Console::IsVisible); - consoleClass.SetMethod("SendCharacter", &Console::SendCharacter); + consoleClass.BindMethod("SendCharacter", &Console::SendCharacter); //consoleClass.SetMethod("SendEvent", &Console::SendEvent); - consoleClass.SetMethod("SetCharacterSize", &Console::SetCharacterSize); - consoleClass.SetMethod("SetSize", &Console::SetSize); + consoleClass.BindMethod("SetCharacterSize", &Console::SetCharacterSize); + consoleClass.BindMethod("SetSize", &Console::SetSize); //consoleClass.SetMethod("SetTextFont", &Console::SetTextFont); - consoleClass.SetMethod("Show", &Console::Show, true); + consoleClass.BindMethod("Show", &Console::Show, true); #endif /*********************************** Ndk::Entity **********************************/ - entityClass.SetMethod("Enable", &Entity::Enable); - entityClass.SetMethod("GetId", &Entity::GetId); - entityClass.SetMethod("GetWorld", &Entity::GetWorld); - entityClass.SetMethod("Kill", &Entity::Kill); - entityClass.SetMethod("IsEnabled", &Entity::IsEnabled); - entityClass.SetMethod("IsValid", &Entity::IsValid); - entityClass.SetMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); - entityClass.SetMethod("RemoveAllComponents", &Entity::RemoveAllComponents); - entityClass.SetMethod("__tostring", &EntityHandle::ToString); + entityClass.BindMethod("Enable", &Entity::Enable); + entityClass.BindMethod("GetId", &Entity::GetId); + entityClass.BindMethod("GetWorld", &Entity::GetWorld); + entityClass.BindMethod("Kill", &Entity::Kill); + entityClass.BindMethod("IsEnabled", &Entity::IsEnabled); + entityClass.BindMethod("IsValid", &Entity::IsValid); + entityClass.BindMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); + entityClass.BindMethod("RemoveAllComponents", &Entity::RemoveAllComponents); + entityClass.BindMethod("__tostring", &EntityHandle::ToString); - entityClass.SetMethod("AddComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + entityClass.BindMethod("AddComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int { int index = 1; ComponentIndex componentIndex = lua.Check(&index); @@ -119,7 +119,7 @@ namespace Ndk return binding.adder(lua, handle); }); - entityClass.SetMethod("GetComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + entityClass.BindMethod("GetComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int { int index = 1; ComponentIndex componentIndex = lua.Check(&index); @@ -183,14 +183,14 @@ namespace Ndk }); /*********************************** Ndk::World **********************************/ - worldClass.SetMethod("CreateEntity", &World::CreateEntity); - worldClass.SetMethod("CreateEntities", &World::CreateEntities); - worldClass.SetMethod("Clear", &World::Clear); + worldClass.BindMethod("CreateEntity", &World::CreateEntity); + worldClass.BindMethod("CreateEntities", &World::CreateEntities); + worldClass.BindMethod("Clear", &World::Clear); #ifndef NDK_SERVER /*********************************** Ndk::GraphicsComponent **********************************/ - graphicsComponent.SetMethod("Attach", &GraphicsComponent::Attach, 0); + graphicsComponent.BindMethod("Attach", &GraphicsComponent::Attach, 0); #endif diff --git a/SDK/src/NDK/LuaBinding_Utility.cpp b/SDK/src/NDK/LuaBinding_Utility.cpp index 65447a0b3..86f4a6f9a 100644 --- a/SDK/src/NDK/LuaBinding_Utility.cpp +++ b/SDK/src/NDK/LuaBinding_Utility.cpp @@ -9,19 +9,19 @@ namespace Ndk void LuaBinding::BindUtility() { /*********************************** Nz::AbstractImage **********************************/ - abstractImage.SetMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); - abstractImage.SetMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); - abstractImage.SetMethod("GetFormat", &Nz::AbstractImage::GetFormat); - abstractImage.SetMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); - abstractImage.SetMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); - abstractImage.SetMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); - abstractImage.SetMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); - abstractImage.SetMethod("GetType", &Nz::AbstractImage::GetType); - abstractImage.SetMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); - abstractImage.SetMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); - abstractImage.SetMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); + abstractImage.BindMethod("GetBytesPerPixel", &Nz::AbstractImage::GetBytesPerPixel); + abstractImage.BindMethod("GetDepth", &Nz::AbstractImage::GetDepth, static_cast(0)); + abstractImage.BindMethod("GetFormat", &Nz::AbstractImage::GetFormat); + abstractImage.BindMethod("GetHeight", &Nz::AbstractImage::GetHeight, static_cast(0)); + abstractImage.BindMethod("GetLevelCount", &Nz::AbstractImage::GetLevelCount); + abstractImage.BindMethod("GetMaxLevel", &Nz::AbstractImage::GetMaxLevel); + abstractImage.BindMethod("GetSize", &Nz::AbstractImage::GetSize, static_cast(0)); + abstractImage.BindMethod("GetType", &Nz::AbstractImage::GetType); + abstractImage.BindMethod("GetWidth", &Nz::AbstractImage::GetWidth, static_cast(0)); + abstractImage.BindMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); + abstractImage.BindMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); - abstractImage.SetMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + abstractImage.BindMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 1U); switch (argCount) @@ -42,7 +42,7 @@ namespace Ndk return 0; }); - abstractImage.SetMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int + abstractImage.BindMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* abstractImage) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 6U); int argIndex = 1; @@ -89,52 +89,52 @@ namespace Ndk }); /*********************************** Nz::Node **********************************/ - nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); + nodeClass.BindMethod("GetBackward", &Nz::Node::GetBackward); //nodeClass.SetMethod("GetChilds", &Nz::Node::GetChilds); - nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); - nodeClass.SetMethod("GetForward", &Nz::Node::GetForward); - nodeClass.SetMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); - nodeClass.SetMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); - nodeClass.SetMethod("GetInheritScale", &Nz::Node::GetInheritScale); - nodeClass.SetMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); + nodeClass.BindMethod("GetDown", &Nz::Node::GetDown); + nodeClass.BindMethod("GetForward", &Nz::Node::GetForward); + nodeClass.BindMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); + nodeClass.BindMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); + nodeClass.BindMethod("GetInheritScale", &Nz::Node::GetInheritScale); + nodeClass.BindMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); //nodeClass.SetMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); - nodeClass.SetMethod("GetInitialScale", &Nz::Node::GetInitialScale); - nodeClass.SetMethod("GetLeft", &Nz::Node::GetLeft); - nodeClass.SetMethod("GetNodeType", &Nz::Node::GetNodeType); + nodeClass.BindMethod("GetInitialScale", &Nz::Node::GetInitialScale); + nodeClass.BindMethod("GetLeft", &Nz::Node::GetLeft); + nodeClass.BindMethod("GetNodeType", &Nz::Node::GetNodeType); //nodeClass.SetMethod("GetParent", &Nz::Node::GetParent); - nodeClass.SetMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); - nodeClass.SetMethod("GetRight", &Nz::Node::GetRight); + nodeClass.BindMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); + nodeClass.BindMethod("GetRight", &Nz::Node::GetRight); //nodeClass.SetMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); - nodeClass.SetMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); + nodeClass.BindMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); //nodeClass.SetMethod("GetTransformMatrix", &Nz::Node::GetTransformMatrix); - nodeClass.SetMethod("GetUp", &Nz::Node::GetUp); + nodeClass.BindMethod("GetUp", &Nz::Node::GetUp); - nodeClass.SetMethod("HasChilds", &Nz::Node::HasChilds); + nodeClass.BindMethod("HasChilds", &Nz::Node::HasChilds); - nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); - nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); - nodeClass.SetMethod("GetForward", &Nz::Node::GetForward); - nodeClass.SetMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); - nodeClass.SetMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); - nodeClass.SetMethod("GetInheritScale", &Nz::Node::GetInheritScale); - nodeClass.SetMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); - nodeClass.SetMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); - nodeClass.SetMethod("GetInitialScale", &Nz::Node::GetInitialScale); - nodeClass.SetMethod("GetLeft", &Nz::Node::GetLeft); - nodeClass.SetMethod("GetNodeType", &Nz::Node::GetNodeType); - nodeClass.SetMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); - nodeClass.SetMethod("GetRight", &Nz::Node::GetRight); - nodeClass.SetMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); - nodeClass.SetMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); - nodeClass.SetMethod("GetUp", &Nz::Node::GetUp); + nodeClass.BindMethod("GetBackward", &Nz::Node::GetBackward); + nodeClass.BindMethod("GetDown", &Nz::Node::GetDown); + nodeClass.BindMethod("GetForward", &Nz::Node::GetForward); + nodeClass.BindMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); + nodeClass.BindMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); + nodeClass.BindMethod("GetInheritScale", &Nz::Node::GetInheritScale); + nodeClass.BindMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); + nodeClass.BindMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); + nodeClass.BindMethod("GetInitialScale", &Nz::Node::GetInitialScale); + nodeClass.BindMethod("GetLeft", &Nz::Node::GetLeft); + nodeClass.BindMethod("GetNodeType", &Nz::Node::GetNodeType); + nodeClass.BindMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); + nodeClass.BindMethod("GetRight", &Nz::Node::GetRight); + nodeClass.BindMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); + nodeClass.BindMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); + nodeClass.BindMethod("GetUp", &Nz::Node::GetUp); - nodeClass.SetMethod("SetInitialPosition", (void(Nz::Node::*)(const Nz::Vector3f&)) &Nz::Node::SetInitialPosition); - nodeClass.SetMethod("SetInitialRotation", (void(Nz::Node::*)(const Nz::Quaternionf&)) &Nz::Node::SetInitialRotation); + nodeClass.BindMethod("SetInitialPosition", (void(Nz::Node::*)(const Nz::Vector3f&)) &Nz::Node::SetInitialPosition); + nodeClass.BindMethod("SetInitialRotation", (void(Nz::Node::*)(const Nz::Quaternionf&)) &Nz::Node::SetInitialRotation); - nodeClass.SetMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local); - nodeClass.SetMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local); + nodeClass.BindMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local); + nodeClass.BindMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local); - nodeClass.SetMethod("Move", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + nodeClass.BindMethod("Move", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int { int argIndex = 1; @@ -145,7 +145,7 @@ namespace Ndk return 0; }); - nodeClass.SetMethod("Rotate", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + nodeClass.BindMethod("Rotate", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int { int argIndex = 1; @@ -156,7 +156,7 @@ namespace Ndk return 0; }); - nodeClass.SetMethod("Scale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + nodeClass.BindMethod("Scale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 4U); @@ -182,7 +182,7 @@ namespace Ndk return 0; }); - nodeClass.SetMethod("SetScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + nodeClass.BindMethod("SetScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 4U); @@ -219,7 +219,7 @@ namespace Ndk return 0; }); - nodeClass.SetMethod("SetInitialScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + nodeClass.BindMethod("SetInitialScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int { unsigned int argCount = std::min(lua.GetStackTop(), 4U); diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index eb4cb51e3..8f9990bef 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -36,6 +36,15 @@ namespace Nz LuaClass(const String& name); + void BindMethod(const String& name, ClassFunc method); + template std::enable_if_t::value> BindMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); + template std::enable_if_t::value> BindMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); + template std::enable_if_t::type>::value> BindMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); + template std::enable_if_t::type>::value> BindMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); + + void BindStaticMethod(const String& name, StaticFunc func); + template void BindStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs); + template void Inherit(LuaClass

& parent); template void Inherit(LuaClass

& parent, ConvertToParent

convertFunc); @@ -46,15 +55,8 @@ namespace Nz void SetConstructor(ConstructorFunc constructor); void SetFinalizer(FinalizerFunc finalizer); void SetGetter(ClassIndexFunc getter); - void SetMethod(const String& name, ClassFunc method); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); - template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); - template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); - void SetStaticMethod(const String& name, StaticFunc func); - template void SetStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs); void SetStaticSetter(StaticIndexFunc getter); private: diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index ffcc4b0d8..913382f99 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -213,18 +213,18 @@ namespace Nz } template - void LuaClass::SetMethod(const String& name, ClassFunc method) + void LuaClass::BindMethod(const String& name, ClassFunc method) { m_methods[name] = method; } template template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) + std::enable_if_t::value> LuaClass::BindMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + BindMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -234,11 +234,11 @@ namespace Nz template template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) + std::enable_if_t::value> LuaClass::BindMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + BindMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -248,11 +248,11 @@ namespace Nz template template - std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) + std::enable_if_t::type>::value> LuaClass::BindMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + BindMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -262,11 +262,11 @@ namespace Nz template template - std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) + std::enable_if_t::type>::value> LuaClass::BindMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + BindMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -287,18 +287,18 @@ namespace Nz } template - void LuaClass::SetStaticMethod(const String& name, StaticFunc method) + void LuaClass::BindStaticMethod(const String& name, StaticFunc method) { m_staticMethods[name] = method; } template template - void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs) + void LuaClass::BindStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs) { typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - SetStaticMethod(name, [func, handler] (LuaInstance& lua) -> int + BindStaticMethod(name, [func, handler] (LuaInstance& lua) -> int { handler.ProcessArgs(lua); From 1a5dd4140755b3e26bb11aaea365108114dca68e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 17:55:21 +0200 Subject: [PATCH 222/229] Network/RUdpConnection: Remove useless arg from Listen Former-commit-id: 94af162bf5fc1e7d06baae8e4121eb5afe10a649 --- include/Nazara/Network/RUdpConnection.hpp | 4 ++-- include/Nazara/Network/RUdpConnection.inl | 4 ++-- src/Nazara/Network/RUdpConnection.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Network/RUdpConnection.hpp b/include/Nazara/Network/RUdpConnection.hpp index 2896ec6ce..b583bdf49 100644 --- a/include/Nazara/Network/RUdpConnection.hpp +++ b/include/Nazara/Network/RUdpConnection.hpp @@ -46,8 +46,8 @@ namespace Nz inline UInt16 GetBoundPort() const; inline SocketError GetLastError() const; - inline bool Listen(NetProtocol protocol, UInt16 port = 64266, unsigned int queueSize = 10); - bool Listen(const IpAddress& address, unsigned int queueSize = 10); + inline bool Listen(NetProtocol protocol, UInt16 port = 64266); + bool Listen(const IpAddress& address); bool PollMessage(RUdpMessage* message); diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index cfb598bb9..da63536c9 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -33,7 +33,7 @@ namespace Nz return m_lastError; } - inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) + inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port) { NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); @@ -56,7 +56,7 @@ namespace Nz } any.SetPort(port); - return Listen(any, queueSize); + return Listen(any); } inline void RUdpConnection::SetProtocolId(UInt32 protocolId) diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp index f8b57cf00..8d2bc5e32 100644 --- a/src/Nazara/Network/RUdpConnection.cpp +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -63,7 +63,7 @@ namespace Nz return Connect(hostnameAddress); } - bool RUdpConnection::Listen(const IpAddress& address, unsigned int queueSize) + bool RUdpConnection::Listen(const IpAddress& address) { if (!InitSocket(address.GetProtocol())) return false; @@ -110,7 +110,7 @@ namespace Nz { PeerData& peer = m_peers[m_peerIterator]; - UInt32 timeSinceLastPacket = m_currentTime - peer.lastPacketTime; + UInt32 timeSinceLastPacket = static_cast(m_currentTime - peer.lastPacketTime); if (timeSinceLastPacket > m_timeBeforeTimeOut) { DisconnectPeer(peer.index); From 76bc70b210ddedfb053c04e4a5bb817a5383048d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 17:56:02 +0200 Subject: [PATCH 223/229] Network/RUdpConnection: Add packet loss simulator Former-commit-id: 8778d54b5b5a9038ec6b9d888cf6c49ad6c5721c --- include/Nazara/Network/RUdpConnection.hpp | 6 +++++- include/Nazara/Network/RUdpConnection.inl | 13 +++++++++++++ src/Nazara/Network/RUdpConnection.cpp | 9 ++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Network/RUdpConnection.hpp b/include/Nazara/Network/RUdpConnection.hpp index b583bdf49..6166d787a 100644 --- a/include/Nazara/Network/RUdpConnection.hpp +++ b/include/Nazara/Network/RUdpConnection.hpp @@ -56,6 +56,8 @@ namespace Nz inline void SetProtocolId(UInt32 protocolId); inline void SetTimeBeforeAck(UInt32 ms); + inline void SimulateNetwork(double packetLoss); + void Update(); RUdpConnection& operator=(const RUdpConnection&) = delete; @@ -137,9 +139,10 @@ namespace Nz UInt64 stateData1; }; - std::unordered_map m_peerByIP; + std::bernoulli_distribution m_packetLossProbability; std::queue m_receivedMessages; std::size_t m_peerIterator; + std::unordered_map m_peerByIP; std::vector m_peers; Bitset m_activeClients; Clock m_clock; @@ -151,6 +154,7 @@ namespace Nz UInt32 m_timeBeforePing; UInt32 m_timeBeforeTimeOut; UInt64 m_currentTime; + bool m_isSimulationEnabled; bool m_shouldAcceptConnections; static std::mt19937_64 s_randomGenerator; diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index da63536c9..b2372285d 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -121,6 +121,19 @@ namespace Nz NazaraError("PacketReliability not handled (0x" + String::Number(reliability, 16) + ')'); return false; } + + inline void RUdpConnection::SimulateNetwork(double packetLoss) + { + NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]"); + + if (packetLoss > 0.0) + { + m_isSimulationEnabled = true; + m_packetLossProbability = std::bernoulli_distribution(packetLoss); + } + else + m_isSimulationEnabled = false; + } } #include diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp index 8d2bc5e32..451d08f1e 100644 --- a/src/Nazara/Network/RUdpConnection.cpp +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -18,6 +18,7 @@ namespace Nz m_timeBeforePing(500'000), //< 0.5s m_timeBeforeTimeOut(10'000'000), //< 10s m_currentTime(0), + m_isSimulationEnabled(false), m_shouldAcceptConnections(true) { } @@ -34,7 +35,7 @@ namespace Nz NetPacket connectionRequestPacket(NetCode_RequestConnection); connectionRequestPacket << client.stateData1; - EnqueuePacket(client, PacketPriority_Immediate, PacketReliability_Unreliable, connectionRequestPacket); + EnqueuePacket(client, PacketPriority_Immediate, PacketReliability_Reliable, connectionRequestPacket); return true; } @@ -349,6 +350,12 @@ namespace Nz if (peer.receivedQueue.find(sequenceId) != peer.receivedQueue.end()) return; //< Ignore + if (m_isSimulationEnabled && m_packetLossProbability(s_randomGenerator)) + { + NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Lost packet " + String::Number(sequenceId) + " from " + peerIp.ToString() + " for simulation purpose"); + return; + } + ///< Receiving a packet from an acknowledged client means the connection works in both ways if (peer.state == PeerState_Aknowledged && packet.GetNetCode() != NetCode_RequestConnection) { From ba176af5cd45fb7f563085253090db8337c6aca7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 18:08:37 +0200 Subject: [PATCH 224/229] Audio/SoundBuffer: Fix duration of large sound files Former-commit-id: be1c5ba7c9960331eeb359d6cbfa714aeb84f479 --- src/Nazara/Audio/SoundBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index 10edc74f8..c01878383 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -105,7 +105,7 @@ namespace Nz m_impl = new SoundBufferImpl; m_impl->buffer = buffer; - m_impl->duration = (1000*sampleCount / (format * sampleRate)); + m_impl->duration = static_cast((1000ULL*sampleCount / (format * sampleRate))); m_impl->format = format; m_impl->sampleCount = sampleCount; m_impl->sampleRate = sampleRate; From b87a8b3f25b2f74b860fe820fa594576babf64ff Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 18:09:22 +0200 Subject: [PATCH 225/229] Audio/Sound: Replace error check by assert Former-commit-id: 76192feaa3a29342b5456a97f660719714be3fe6 --- src/Nazara/Audio/Sound.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 31ef3af27..192bbb96b 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -42,13 +42,7 @@ namespace Nz UInt32 Sound::GetDuration() const { - #if NAZARA_AUDIO_SAFE - if (!m_buffer) - { - NazaraError("Invalid sound buffer"); - return 0; - } - #endif + NazaraAssert(m_buffer, "Invalid sound buffer"); return m_buffer->GetDuration(); } From 2415002fc515ad9a498f3990542b14530a6ebe32 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 19:28:20 +0200 Subject: [PATCH 226/229] Audio/Sound: Fix GetPlayingOffset/SetPlayingOffset on some implementations Former-commit-id: 64223409d16af0d8ada3edeb2eb24366c5e312ca --- src/Nazara/Audio/Sound.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 192bbb96b..7198a01d6 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -49,10 +49,10 @@ namespace Nz UInt32 Sound::GetPlayingOffset() const { - ALfloat seconds = -1.f; - alGetSourcef(m_source, AL_SEC_OFFSET, &seconds); + ALint samples = 0; + alGetSourcei(m_source, AL_SAMPLE_OFFSET, &samples); - return static_cast(seconds*1000); + return static_cast(1000ULL * samples / m_buffer->GetSampleRate()); } SoundStatus Sound::GetStatus() const @@ -160,7 +160,7 @@ namespace Nz void Sound::SetPlayingOffset(UInt32 offset) { - alSourcef(m_source, AL_SEC_OFFSET, offset/1000.f); + alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast(offset/1000.f * m_buffer->GetSampleRate())); } void Sound::Stop() From 6d146e30c868c0ec933c2bbe0cce467200d937c3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 19:28:44 +0200 Subject: [PATCH 227/229] Audio/Music: Fix GetPlayingOffset and SetPlayingOffset Former-commit-id: 71d19338612e84105723e28b4fc38510472e89ef --- src/Nazara/Audio/Music.cpp | 83 ++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index be13419dc..aba84b5ff 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,9 @@ namespace Nz ALenum audioFormat; std::unique_ptr stream; std::vector chunkSamples; + Mutex bufferLock; Thread thread; + UInt64 processedSamples; bool loop = false; bool streaming = false; unsigned int sampleRate; @@ -36,15 +39,9 @@ namespace Nz bool Music::Create(SoundStream* soundStream) { - Destroy(); + NazaraAssert(soundStream, "Invalid stream"); - #if NAZARA_AUDIO_SAFE - if (!soundStream) - { - NazaraError("Sound stream must be valid"); - return false; - } - #endif + Destroy(); AudioFormat format = soundStream->GetFormat(); @@ -54,6 +51,8 @@ namespace Nz m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples m_impl->stream.reset(soundStream); + SetPlayingOffset(0); + return true; } @@ -116,9 +115,14 @@ namespace Nz return 0; } #endif + + // Prevent music thread from enqueing new buffers while we're getting the count + Nz::LockGuard lock(m_impl->bufferLock); - ///TODO - return 0; + ALint samples = 0; + alGetSourcei(m_source, AL_SAMPLE_OFFSET, &samples); + + return (1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate; } UInt32 Music::GetSampleCount() const @@ -144,7 +148,7 @@ namespace Nz } #endif - return m_impl->stream->GetSampleRate(); + return m_impl->sampleRate; } SoundStatus Music::GetStatus() const @@ -209,22 +213,29 @@ namespace Nz } #endif - // Nous sommes déjà en train de jouer + // Maybe we are already playing if (m_impl->streaming) { - // Peut-être sommes-nous en pause - if (GetStatus() != SoundStatus_Playing) - alSourcePlay(m_source); + switch (GetStatus()) + { + case SoundStatus_Playing: + SetPlayingOffset(0); + break; - return; + case SoundStatus_Paused: + alSourcePlay(m_source); + break; + + default: + break; // We shouldn't be stopped + } + } + else + { + // Starting streaming's thread + m_impl->streaming = true; + m_impl->thread = Thread(&Music::MusicThread, this); } - - // Lancement du thread de streaming - m_impl->stream->Seek(0); - m_impl->streaming = true; - m_impl->thread = Thread(&Music::MusicThread, this); - - return; } void Music::SetPlayingOffset(UInt32 offset) @@ -237,7 +248,16 @@ namespace Nz } #endif - ///TODO + bool isPlaying = m_impl->streaming; + + if (isPlaying) + Stop(); + + m_impl->stream->Seek(offset); + m_impl->processedSamples = UInt64(offset) * m_impl->sampleRate * m_impl->stream->GetFormat() / 1000ULL; + + if (isPlaying) + Play(); } void Music::Stop() @@ -312,18 +332,29 @@ namespace Nz break; } + Nz::LockGuard lock(m_impl->bufferLock); + // On traite les buffers lus ALint processedCount = 0; alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); - - ALuint buffer; while (processedCount--) { + ALuint buffer; alSourceUnqueueBuffers(m_source, 1, &buffer); + + ALint bits, size; + alGetBufferi(buffer, AL_BITS, &bits); + alGetBufferi(buffer, AL_SIZE, &size); + + if (bits != 0) + m_impl->processedSamples += (8 * size) / bits; + if (FillAndQueueBuffer(buffer)) break; } + lock.Unlock(); + // On retourne dormir un peu Thread::Sleep(50); } From 19e4a35e463f66bd049f65d69de7033ee524a5bc Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 19:29:01 +0200 Subject: [PATCH 228/229] Sdk/Systems: Fix update rate Former-commit-id: 6267d307c07009f921eb2c7c14eb0904a3a0e48a --- SDK/include/NDK/BaseSystem.inl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 0c86ddfdd..0c2811ac0 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -60,14 +60,16 @@ namespace Ndk { if (m_updateRate > 0.f) { - m_updateCounter -= elapsedTime; - if (m_updateCounter >= 0.f) - return; + m_updateCounter += elapsedTime; - m_updateCounter += m_updateRate; + while (m_updateCounter >= m_updateRate) + { + OnUpdate(m_updateRate); + m_updateCounter -= m_updateRate; + } } - - OnUpdate(elapsedTime); + else + OnUpdate(elapsedTime); } template From 922e49accb6471276e448ae72fa1933933ba24e5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 19:39:34 +0200 Subject: [PATCH 229/229] Ignore more VS stuff Former-commit-id: 3239565791c7e4841d373d60a55aa5ffa0a56a36 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5fe1f32e7..d671b209b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ build/**/*.slo build/**/*.lo build/**/*.o build/**/*.obj +build/**/*.obj.enc # Compiled Dynamic libraries build/**/*.so