diff --git a/.gitignore b/.gitignore index 86ee68bd1..3bfc4dcac 100644 --- a/.gitignore +++ b/.gitignore @@ -15,12 +15,14 @@ examples/bin/*.exe examples/bin/*.pdb examples/bin/*.dll examples/bin/*.so +examples/bin/Demo* # Unit tests tests/*.exe tests/*.pdb tests/*.dll tests/*.so +tests/NazaraUnitTests* # Example generated files examples/bin/HardwareInfo.txt @@ -49,6 +51,7 @@ build/**/*.project # GMake build/**/*.make +build/**/*.d # Visual Studio build/**/*.pdb @@ -60,7 +63,7 @@ build/**/*.vcxprojResolveAssemblyReference.cache build/**/*.nativecodeanalysis.all.xml build/**/*.nativecodeanalysis.xml build/**/*.VC.opendb -build/**/*.VC.db +build/**/*.VC.db* # Compiled Object files build/**/*.slo diff --git a/Doxyfile b/Doxyfile index 04a327a38..116ba2c2a 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "Nazara Engine" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.2 +PROJECT_NUMBER = 0.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/SDK/include/NDK/Algorithm.hpp b/SDK/include/NDK/Algorithm.hpp index da75f4ff7..9e29f53cf 100644 --- a/SDK/include/NDK/Algorithm.hpp +++ b/SDK/include/NDK/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Algorithm.inl b/SDK/include/NDK/Algorithm.inl index fbdad365b..54339ce38 100644 --- a/SDK/include/NDK/Algorithm.inl +++ b/SDK/include/NDK/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index b3f803fe1..2ada48555 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index 0b4f2ce10..e7f074c3e 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index 0a48c394d..427fb017e 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -23,20 +23,22 @@ namespace Ndk using Factory = std::function; BaseComponent(ComponentIndex componentIndex); - BaseComponent(const BaseComponent&) = default; BaseComponent(BaseComponent&&) = default; virtual ~BaseComponent(); virtual std::unique_ptr Clone() const = 0; + inline const EntityHandle& GetEntity() const; ComponentIndex GetIndex() const; inline static ComponentIndex GetMaxComponentIndex(); - BaseComponent& operator=(const BaseComponent&) = default; + BaseComponent& operator=(const BaseComponent&) = delete; BaseComponent& operator=(BaseComponent&&) = default; protected: + BaseComponent(const BaseComponent&) = default; + ComponentIndex m_componentIndex; EntityHandle m_entity; @@ -47,6 +49,7 @@ namespace Ndk virtual void OnComponentAttached(BaseComponent& component); virtual void OnComponentDetached(BaseComponent& component); virtual void OnDetached(); + virtual void OnEntityDestruction(); void SetEntity(Entity* entity); diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index 0e8af931f..0596eb589 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -19,11 +19,19 @@ namespace Ndk { } + /*! + * \brief Gets the entity owning this component + * \return A handle to the entity owning this component, may be invalid if no entity owns it. + */ + inline const EntityHandle& BaseComponent::GetEntity() const + { + return m_entity; + } + /*! * \brief Gets the index of the component * \return Index of the component */ - inline ComponentIndex BaseComponent::GetIndex() const { return m_componentIndex; diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 7433f7d04..99dcbf768 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace Ndk @@ -33,7 +34,7 @@ namespace Ndk bool Filters(const Entity* entity) const; - inline const std::vector& GetEntities() const; + inline const EntityList& GetEntities() const; inline SystemIndex GetIndex() const; inline int GetUpdateOrder() const; inline float GetUpdateRate() const; @@ -84,12 +85,11 @@ namespace Ndk static inline bool Initialize(); static inline void Uninitialize(); - std::vector m_entities; - Nz::Bitset m_entityBits; Nz::Bitset<> m_excludedComponents; mutable Nz::Bitset<> m_filterResult; Nz::Bitset<> m_requiredAnyComponents; Nz::Bitset<> m_requiredComponents; + EntityList m_entities; SystemIndex m_systemIndex; World* m_world; bool m_updateEnabled; diff --git a/SDK/include/NDK/BaseSystem.inl b/SDK/include/NDK/BaseSystem.inl index 79971e3d6..5969dd8e3 100644 --- a/SDK/include/NDK/BaseSystem.inl +++ b/SDK/include/NDK/BaseSystem.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -56,7 +56,7 @@ namespace Ndk * \return A constant reference to the list of entities */ - inline const std::vector& BaseSystem::GetEntities() const + inline const EntityList& BaseSystem::GetEntities() const { return m_entities; } @@ -121,10 +121,7 @@ namespace Ndk inline bool BaseSystem::HasEntity(const Entity* entity) const { - if (!entity) - return false; - - return m_entityBits.UnboundedTest(entity->GetId()); + return m_entities.Has(entity); } /*! @@ -288,9 +285,7 @@ namespace Ndk { NazaraAssert(entity, "Invalid entity"); - m_entities.emplace_back(entity); - m_entityBits.UnboundedSet(entity->GetId(), true); - + m_entities.Insert(entity); entity->RegisterSystem(m_systemIndex); OnEntityAdded(entity); @@ -308,14 +303,7 @@ namespace Ndk { NazaraAssert(entity, "Invalid entity"); - auto it = std::find(m_entities.begin(), m_entities.end(), *entity); - NazaraAssert(it != m_entities.end(), "Entity is not part of this system"); - - // To avoid moving a lot of handles, we swap and pop - std::swap(*it, m_entities.back()); - m_entities.pop_back(); // We get it out of the vector - - m_entityBits.Reset(entity->GetId()); + m_entities.Remove(entity); entity->UnregisterSystem(m_systemIndex); OnEntityRemoved(entity); // And we alert our callback @@ -360,7 +348,7 @@ namespace Ndk } /*! - * \brief Uninitializes the BaseSystem + * \brief Uninitialize the BaseSystem */ inline void BaseSystem::Uninitialize() diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index 1e6fe7c64..723e93e80 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -12,9 +12,11 @@ #include #include #include +#include #include #include #include +#include namespace Ndk { @@ -32,28 +34,39 @@ namespace Ndk BaseWidget(BaseWidget&&) = default; virtual ~BaseWidget(); - template T& Add(Args&&... args); + template T* Add(Args&&... args); inline void AddChild(std::unique_ptr&& widget); inline void Center(); + inline void Destroy(); + void EnableBackground(bool enable); //virtual BaseWidget* Clone() const = 0; + inline const Nz::Color& GetBackgroundColor() const; inline Canvas* GetCanvas(); + inline Nz::SystemCursor GetCursor() const; inline const Padding& GetPadding() const; + inline Nz::Vector2f GetContentOrigin() const; inline const Nz::Vector2f& GetContentSize() const; inline Nz::Vector2f GetSize() const; + inline bool IsVisible() const; + void GrabKeyboard(); virtual void ResizeToContent() = 0; + void SetBackgroundColor(const Nz::Color& color); + void SetCursor(Nz::SystemCursor systemCursor); inline void SetContentSize(const Nz::Vector2f& size); inline void SetPadding(float left, float top, float right, float bottom); void SetSize(const Nz::Vector2f& size); + void Show(bool show = true); + BaseWidget& operator=(const BaseWidget&) = delete; BaseWidget& operator=(BaseWidget&&) = default; @@ -78,12 +91,21 @@ namespace Ndk virtual void OnMouseButtonPress(int x, int y, Nz::Mouse::Button button); virtual void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button); virtual void OnMouseExit(); + virtual void OnParentResized(const Nz::Vector2f& newSize); virtual void OnTextEntered(char32_t character, bool repeated); private: inline BaseWidget(); + inline void DestroyChild(BaseWidget* widget); + void DestroyChildren(); + inline bool IsRegisteredToCanvas() const; + inline void NotifyParentResized(const Nz::Vector2f& newSize); + void RegisterToCanvas(); inline void UpdateCanvasIndex(std::size_t index); + void UnregisterFromCanvas(); + + static constexpr std::size_t InvalidCanvasIndex = std::numeric_limits::max(); std::size_t m_canvasIndex; std::vector m_entities; @@ -94,8 +116,10 @@ namespace Ndk WorldHandle m_world; Nz::Color m_backgroundColor; Nz::SpriteRef m_backgroundSprite; + Nz::SystemCursor m_cursor; Nz::Vector2f m_contentSize; BaseWidget* m_widgetParent; + bool m_visible; }; } diff --git a/SDK/include/NDK/BaseWidget.inl b/SDK/include/NDK/BaseWidget.inl index 0b13ee7c7..e84a67a49 100644 --- a/SDK/include/NDK/BaseWidget.inl +++ b/SDK/include/NDK/BaseWidget.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -9,26 +9,31 @@ namespace Ndk { inline BaseWidget::BaseWidget() : - m_backgroundColor(Nz::Color(230, 230, 230, 255)), + m_canvasIndex(InvalidCanvasIndex), m_canvas(nullptr), + m_backgroundColor(Nz::Color(230, 230, 230, 255)), + m_cursor(Nz::SystemCursor_Default), m_contentSize(50.f, 50.f), - m_widgetParent(nullptr) + m_widgetParent(nullptr), + m_visible(true) { SetPadding(5.f, 5.f, 5.f, 5.f); } template - inline T& BaseWidget::Add(Args&&... args) + inline T* BaseWidget::Add(Args&&... args) { std::unique_ptr widget = std::make_unique(this, std::forward(args)...); - T& widgetRef = *widget; + T* widgetPtr = widget.get(); AddChild(std::move(widget)); - return widgetRef; + return widgetPtr; } inline void BaseWidget::AddChild(std::unique_ptr&& widget) { + widget->Show(m_visible); + widget->SetParent(this); m_children.emplace_back(std::move(widget)); } @@ -41,16 +46,31 @@ namespace Ndk SetPosition((parentSize.x - mySize.x) / 2.f, (parentSize.y - mySize.y) / 2.f); } + inline const Nz::Color& BaseWidget::GetBackgroundColor() const + { + return m_backgroundColor; + } + inline Canvas* BaseWidget::GetCanvas() { return m_canvas; } + inline Nz::SystemCursor BaseWidget::GetCursor() const + { + return m_cursor; + } + inline const BaseWidget::Padding& BaseWidget::GetPadding() const { return m_padding; } + inline Nz::Vector2f BaseWidget::GetContentOrigin() const + { + return { m_padding.left, m_padding.top }; + } + inline const Nz::Vector2f& BaseWidget::GetContentSize() const { return m_contentSize; @@ -61,10 +81,16 @@ namespace Ndk return Nz::Vector2f(m_contentSize.x + m_padding.left + m_padding.right, m_contentSize.y + m_padding.top + m_padding.bottom); } + inline bool BaseWidget::IsVisible() const + { + return m_visible; + } + inline void BaseWidget::SetContentSize(const Nz::Vector2f& size) { + NotifyParentResized(size); m_contentSize = size; - + Layout(); } @@ -78,6 +104,17 @@ namespace Ndk Layout(); } + inline bool BaseWidget::IsRegisteredToCanvas() const + { + return m_canvas && m_canvasIndex != InvalidCanvasIndex; + } + + inline void BaseWidget::NotifyParentResized(const Nz::Vector2f& newSize) + { + for (const auto& widgetPtr : m_children) + widgetPtr->OnParentResized(newSize); + } + inline void BaseWidget::UpdateCanvasIndex(std::size_t index) { m_canvasIndex = index; diff --git a/SDK/include/NDK/Canvas.hpp b/SDK/include/NDK/Canvas.hpp index a8da5d04e..0cc314b73 100644 --- a/SDK/include/NDK/Canvas.hpp +++ b/SDK/include/NDK/Canvas.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace Ndk @@ -20,10 +21,10 @@ namespace Ndk public: struct Padding; - inline Canvas(WorldHandle world, Nz::EventHandler& eventHandler); + inline Canvas(WorldHandle world, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController); Canvas(const Canvas&) = delete; Canvas(Canvas&&) = delete; - ~Canvas() = default; + inline ~Canvas(); inline const WorldHandle& GetWorld() const; @@ -33,9 +34,8 @@ namespace Ndk Canvas& operator=(Canvas&&) = delete; protected: - void Layout() override; - - void NotifyWidgetUpdate(std::size_t index); + inline void NotifyWidgetBoxUpdate(std::size_t index); + inline void NotifyWidgetCursorUpdate(std::size_t index); std::size_t RegisterWidget(BaseWidget* widget); @@ -56,6 +56,7 @@ namespace Ndk { BaseWidget* widget; Nz::Boxf box; + Nz::SystemCursor cursor; }; NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot); @@ -67,6 +68,7 @@ namespace Ndk NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot); std::vector m_widgetBoxes; + Nz::CursorControllerHandle m_cursorController; const WidgetBox* m_hoveredWidget; BaseWidget* m_keyboardOwner; WorldHandle m_world; diff --git a/SDK/include/NDK/Canvas.inl b/SDK/include/NDK/Canvas.inl index d0d05bf12..3dd5de87f 100644 --- a/SDK/include/NDK/Canvas.inl +++ b/SDK/include/NDK/Canvas.inl @@ -1,18 +1,25 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include namespace Ndk { - inline Canvas::Canvas(WorldHandle world, Nz::EventHandler& eventHandler) : + inline Canvas::Canvas(WorldHandle world, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController) : + m_cursorController(cursorController), m_hoveredWidget(nullptr), m_keyboardOwner(nullptr), m_world(std::move(world)) { m_canvas = this; + m_widgetParent = nullptr; + // Register ourselves as a widget to handle cursor change + RegisterToCanvas(); + + // Connect to every meaningful event m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, this, &Canvas::OnKeyPressed); m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, this, &Canvas::OnKeyReleased); m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, this, &Canvas::OnMouseButtonPressed); @@ -20,6 +27,18 @@ namespace Ndk m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnMouseMoved); m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, this, &Canvas::OnMouseLeft); m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnTextEntered); + + // Disable padding by default + SetPadding(0.f, 0.f, 0.f, 0.f); + } + + inline Canvas::~Canvas() + { + // Destroy children explicitly because they signal us when getting destroyed, and that can't happen after our own destruction + DestroyChildren(); + + // Prevent our parent from trying to call us + m_canvasIndex = InvalidCanvasIndex; } inline const WorldHandle& Canvas::GetWorld() const @@ -27,6 +46,25 @@ namespace Ndk return m_world; } + inline void Canvas::NotifyWidgetBoxUpdate(std::size_t index) + { + WidgetBox& entry = m_widgetBoxes[index]; + + Nz::Vector3f pos = entry.widget->GetPosition(); + Nz::Vector2f size = entry.widget->GetContentSize(); + + entry.box.Set(pos.x, pos.y, pos.z, size.x, size.y, 1.f); + } + + inline void Canvas::NotifyWidgetCursorUpdate(std::size_t index) + { + WidgetBox& entry = m_widgetBoxes[index]; + + entry.cursor = entry.widget->GetCursor(); + if (m_cursorController && m_hoveredWidget == &entry) + m_cursorController->UpdateCursor(Nz::Cursor::Get(entry.cursor)); + } + inline void Ndk::Canvas::SetKeyboardOwner(BaseWidget* widget) { m_keyboardOwner = widget; diff --git a/SDK/include/NDK/Component.hpp b/SDK/include/NDK/Component.hpp index b0f61fd92..14afd253b 100644 --- a/SDK/include/NDK/Component.hpp +++ b/SDK/include/NDK/Component.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Component.inl b/SDK/include/NDK/Component.inl index 6ca3f1944..a629dc8b4 100644 --- a/SDK/include/NDK/Component.inl +++ b/SDK/include/NDK/Component.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index 5a9efe742..f4a29f2e4 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -44,7 +44,7 @@ namespace Ndk const Nz::Frustumf& GetFrustum() const override; inline unsigned int GetLayer() const; const Nz::Matrix4f& GetProjectionMatrix() const override; - inline Nz::ProjectionType GetProjectionType() const; + Nz::ProjectionType GetProjectionType() const override; inline const Nz::Vector2f& GetSize() const; const Nz::RenderTarget* GetTarget() const override; inline const Nz::Rectf& GetTargetRegion() const; diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index 9aadfd509..1018f9f3d 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -39,6 +39,7 @@ namespace Ndk inline CameraComponent::CameraComponent(const CameraComponent& camera) : Component(camera), AbstractViewer(camera), + HandledObject(camera), m_visibilityHash(camera.m_visibilityHash), m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), @@ -116,16 +117,6 @@ namespace Ndk return m_layer; } - /*! - * \brief Gets the projection type of the camera - * \return Projection type of the camera - */ - - inline Nz::ProjectionType CameraComponent::GetProjectionType() const - { - return m_projectionType; - } - /*! * \brief Gets the size of the camera * \return Size of the camera diff --git a/SDK/include/NDK/Components/CollisionComponent2D.hpp b/SDK/include/NDK/Components/CollisionComponent2D.hpp index b282a850e..28c3637a2 100644 --- a/SDK/include/NDK/Components/CollisionComponent2D.hpp +++ b/SDK/include/NDK/Components/CollisionComponent2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/CollisionComponent2D.inl b/SDK/include/NDK/Components/CollisionComponent2D.inl index 62bf422cb..147e8ec32 100644 --- a/SDK/include/NDK/Components/CollisionComponent2D.inl +++ b/SDK/include/NDK/Components/CollisionComponent2D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/CollisionComponent3D.hpp b/SDK/include/NDK/Components/CollisionComponent3D.hpp index 9a9671660..992e73053 100644 --- a/SDK/include/NDK/Components/CollisionComponent3D.hpp +++ b/SDK/include/NDK/Components/CollisionComponent3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/CollisionComponent3D.inl b/SDK/include/NDK/Components/CollisionComponent3D.inl index d5dfeaacc..7d82252af 100644 --- a/SDK/include/NDK/Components/CollisionComponent3D.inl +++ b/SDK/include/NDK/Components/CollisionComponent3D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 418500a96..68961b99a 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -51,6 +51,9 @@ namespace Ndk inline void RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const; + inline void UpdateLocalMatrix(const Nz::InstancedRenderable* instancedRenderable, const Nz::Matrix4f& localMatrix); + inline void UpdateRenderOrder(const Nz::InstancedRenderable* instancedRenderable, int renderOrder); + static ComponentIndex componentIndex; private: diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 6ca950e24..34bd57dd9 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -142,6 +142,32 @@ namespace Ndk } } + inline void GraphicsComponent::UpdateLocalMatrix(const Nz::InstancedRenderable* instancedRenderable, const Nz::Matrix4f& localMatrix) + { + for (auto& renderable : m_renderables) + { + if (renderable.renderable == instancedRenderable) + { + renderable.data.localMatrix = localMatrix; + + InvalidateBoundingVolume(); + break; + } + } + } + + inline void GraphicsComponent::UpdateRenderOrder(const Nz::InstancedRenderable* instancedRenderable, int renderOrder) + { + for (auto& renderable : m_renderables) + { + if (renderable.renderable == instancedRenderable) + { + renderable.data.renderOrder = renderOrder; + break; + } + } + } + /*! * \brief Invalidates the bounding volume */ diff --git a/SDK/include/NDK/Components/LightComponent.hpp b/SDK/include/NDK/Components/LightComponent.hpp index 80f84a759..ba1c5f5c7 100644 --- a/SDK/include/NDK/Components/LightComponent.hpp +++ b/SDK/include/NDK/Components/LightComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/LightComponent.inl b/SDK/include/NDK/Components/LightComponent.inl index ba11703c5..10237b8ac 100644 --- a/SDK/include/NDK/Components/LightComponent.inl +++ b/SDK/include/NDK/Components/LightComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/ListenerComponent.hpp b/SDK/include/NDK/Components/ListenerComponent.hpp index a2b9d59d2..6e4b8284f 100644 --- a/SDK/include/NDK/Components/ListenerComponent.hpp +++ b/SDK/include/NDK/Components/ListenerComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/ListenerComponent.inl b/SDK/include/NDK/Components/ListenerComponent.inl index f2276e439..8728ce9bc 100644 --- a/SDK/include/NDK/Components/ListenerComponent.inl +++ b/SDK/include/NDK/Components/ListenerComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/NodeComponent.hpp b/SDK/include/NDK/Components/NodeComponent.hpp index c2a4eeb83..a04f9b333 100644 --- a/SDK/include/NDK/Components/NodeComponent.hpp +++ b/SDK/include/NDK/Components/NodeComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/NodeComponent.inl b/SDK/include/NDK/Components/NodeComponent.inl index 0150cbbfa..0e953c86e 100644 --- a/SDK/include/NDK/Components/NodeComponent.inl +++ b/SDK/include/NDK/Components/NodeComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp index 6ad3e3981..dd40f7aaa 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.inl b/SDK/include/NDK/Components/ParticleEmitterComponent.inl index 7f8e62cd8..292a2ed8f 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.inl +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/ParticleGroupComponent.hpp b/SDK/include/NDK/Components/ParticleGroupComponent.hpp index 549a6df5c..533eb907e 100644 --- a/SDK/include/NDK/Components/ParticleGroupComponent.hpp +++ b/SDK/include/NDK/Components/ParticleGroupComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/ParticleGroupComponent.inl b/SDK/include/NDK/Components/ParticleGroupComponent.inl index 591e78605..dc3072faa 100644 --- a/SDK/include/NDK/Components/ParticleGroupComponent.inl +++ b/SDK/include/NDK/Components/ParticleGroupComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index 90dd7a5e6..2bbe693a1 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -55,6 +55,7 @@ namespace Ndk void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; + void OnEntityDestruction() override; std::unique_ptr m_object; }; diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.inl b/SDK/include/NDK/Components/PhysicsComponent2D.inl index 312e23e3a..7aea6dca6 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent2D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/PhysicsComponent3D.hpp b/SDK/include/NDK/Components/PhysicsComponent3D.hpp index 9fb1bb45e..8be86537e 100644 --- a/SDK/include/NDK/Components/PhysicsComponent3D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -62,6 +62,7 @@ namespace Ndk void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; + void OnEntityDestruction() override; std::unique_ptr m_object; }; diff --git a/SDK/include/NDK/Components/PhysicsComponent3D.inl b/SDK/include/NDK/Components/PhysicsComponent3D.inl index cad098af8..72646e16a 100644 --- a/SDK/include/NDK/Components/PhysicsComponent3D.inl +++ b/SDK/include/NDK/Components/PhysicsComponent3D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/VelocityComponent.hpp b/SDK/include/NDK/Components/VelocityComponent.hpp index 909adf4d4..39cdd9f1a 100644 --- a/SDK/include/NDK/Components/VelocityComponent.hpp +++ b/SDK/include/NDK/Components/VelocityComponent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Components/VelocityComponent.inl b/SDK/include/NDK/Components/VelocityComponent.inl index e72eca8b7..2cf4f1ec3 100644 --- a/SDK/include/NDK/Components/VelocityComponent.inl +++ b/SDK/include/NDK/Components/VelocityComponent.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 59a98df0d..9635373e0 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -19,7 +19,7 @@ namespace Nz { - class LuaInstance; + class LuaState; } namespace Ndk @@ -32,7 +32,7 @@ namespace Ndk class NDK_API Console : public Nz::Node, public Nz::HandledObject { public: - Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance); + Console(World& world, const Nz::Vector2f& size, Nz::LuaState& state); Console(const Console& console) = delete; Console(Console&& console) = default; ~Console() = default; @@ -83,7 +83,7 @@ namespace Ndk EntityOwner m_input; EntityOwner m_inputBackground; Nz::FontRef m_defaultFont; - Nz::LuaInstance& m_instance; + Nz::LuaState& m_state; Nz::SpriteRef m_historyBackgroundSprite; Nz::SpriteRef m_inputBackgroundSprite; Nz::SimpleTextDrawer m_historyDrawer; diff --git a/SDK/include/NDK/Console.inl b/SDK/include/NDK/Console.inl index 94a6daf91..c97adda20 100644 --- a/SDK/include/NDK/Console.inl +++ b/SDK/include/NDK/Console.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index dbe77815c..5419da0d2 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,14 +17,17 @@ namespace Ndk { class BaseComponent; + class BaseSystem; class Entity; + class EntityList; class World; using EntityHandle = Nz::ObjectHandle; class NDK_API Entity : public Nz::HandledObject { - friend class BaseSystem; + friend BaseSystem; + friend EntityList; friend World; public: @@ -65,6 +69,8 @@ namespace Ndk Entity& operator=(const Entity&) = delete; Entity& operator=(Entity&&) = delete; + NazaraSignal(OnEntityDestruction, Entity* /*entity*/); + private: Entity(World* world, EntityId id); @@ -75,13 +81,16 @@ namespace Ndk inline Nz::Bitset<>& GetRemovedComponentBits(); + inline void RegisterEntityList(EntityList* list); inline void RegisterSystem(SystemIndex index); inline void SetWorld(World* world) noexcept; + inline void UnregisterEntityList(EntityList* list); inline void UnregisterSystem(SystemIndex index); std::vector> m_components; + std::vector m_containedInLists; Nz::Bitset<> m_componentBits; Nz::Bitset<> m_removedComponentBits; Nz::Bitset<> m_systemBits; diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index 535f2c1f4..adb2153d8 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -257,11 +258,10 @@ namespace Ndk return m_removedComponentBits; } - /*! - * \brief Registers a system for the entity - * - * \param index Index of the system - */ + inline void Entity::RegisterEntityList(EntityList* list) + { + m_containedInLists.push_back(list); + } inline void Entity::RegisterSystem(SystemIndex index) { @@ -289,6 +289,16 @@ namespace Ndk * \param index Index of the system */ + inline void Entity::UnregisterEntityList(EntityList* list) + { + auto it = std::find(m_containedInLists.begin(), m_containedInLists.end(), list); + assert(it != m_containedInLists.end()); + + // Swap and pop idiom + *it = m_containedInLists.back(); + m_containedInLists.pop_back(); + } + inline void Entity::UnregisterSystem(SystemIndex index) { m_systemBits.UnboundedReset(index); diff --git a/SDK/include/NDK/EntityList.hpp b/SDK/include/NDK/EntityList.hpp index 006967413..8303f7fa4 100644 --- a/SDK/include/NDK/EntityList.hpp +++ b/SDK/include/NDK/EntityList.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -15,46 +15,68 @@ namespace Ndk { class NDK_API EntityList { - public: - using Container = std::vector; + friend Entity; - EntityList() = default; - ~EntityList() = default; + public: + class iterator; + friend iterator; + using size_type = std::size_t; + + inline EntityList(); + inline EntityList(const EntityList& entityList); + inline EntityList(EntityList&& entityList) noexcept; + inline ~EntityList(); inline void Clear(); - inline bool Has(const Entity* entity); - inline bool Has(EntityId entity); + inline bool Has(const Entity* entity) const; + inline bool Has(EntityId entity) const; inline void Insert(Entity* entity); inline void Remove(Entity* entity); // STL API - inline Container::iterator begin(); - inline Container::const_iterator begin() const; - - inline Container::const_iterator cbegin() const; - inline Container::const_iterator cend() const; - inline Container::const_reverse_iterator crbegin() const; - inline Container::const_reverse_iterator crend() const; - + inline iterator begin() const; inline bool empty() const; + inline iterator end() const; + inline size_type size() const; - inline Container::iterator end(); - inline Container::const_iterator end() const; - - inline Container::reverse_iterator rbegin(); - inline Container::const_reverse_iterator rbegin() const; - - inline Container::reverse_iterator rend(); - inline Container::const_reverse_iterator rend() const; - - inline Container::size_type size() const; + inline EntityList& operator=(const EntityList& entityList); + inline EntityList& operator=(EntityList&& entityList) noexcept; private: - std::vector m_entities; + inline std::size_t FindNext(std::size_t currentId) const; + inline World* GetWorld() const; + inline void NotifyEntityDestruction(const Entity* entity); + Nz::Bitset m_entityBits; + World* m_world; + }; + + class NDK_API EntityList::iterator : public std::iterator + { + friend EntityList; + + public: + inline iterator(const iterator& it); + + const EntityHandle& operator*() const; + + inline iterator& operator=(const iterator& it); + inline iterator& operator++(); + inline iterator operator++(int); + + friend inline bool operator==(const iterator& lhs, const iterator& rhs); + friend inline bool operator!=(const iterator& lhs, const iterator& rhs); + + friend inline void swap(iterator& lhs, iterator& rhs); + + private: + inline iterator(const EntityList* world, std::size_t nextId); + + std::size_t m_nextEntityId; + const EntityList* m_list; }; } diff --git a/SDK/include/NDK/EntityList.inl b/SDK/include/NDK/EntityList.inl index 224fdd1dc..8d871e2c6 100644 --- a/SDK/include/NDK/EntityList.inl +++ b/SDK/include/NDK/EntityList.inl @@ -1,7 +1,8 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include #include @@ -14,24 +15,71 @@ namespace Ndk */ /*! - * \brief Clears the set from every entities + * \brief Construct a new entity list */ - - inline void EntityList::Clear() + inline EntityList::EntityList() : + m_world(nullptr) { - m_entities.clear(); - m_entityBits.Clear(); } /*! - * \brief Checks whether or not the set contains the entity + * \brief Construct a new entity list by copying another one + */ + inline EntityList::EntityList(const EntityList& entityList) : + m_entityBits(entityList.m_entityBits), + m_world(entityList.m_world) + { + for (const Ndk::EntityHandle& entity : *this) + entity->RegisterEntityList(this); + } + + /*! + * \brief Construct a new entity list by moving a list into this one + */ + inline EntityList::EntityList(EntityList&& entityList) noexcept : + m_entityBits(std::move(entityList.m_entityBits)), + m_world(entityList.m_world) + { + for (const Ndk::EntityHandle& entity : *this) + { + entity->UnregisterEntityList(&entityList); + entity->RegisterEntityList(this); + } + } + + inline EntityList::~EntityList() + { + for (const Ndk::EntityHandle& entity : *this) + entity->UnregisterEntityList(this); + } + + + /*! + * \brief Clears the set from every entities + * + * \remark This resets the implicit world member, allowing you to insert entities from a different world than previously + */ + inline void EntityList::Clear() + { + for (const Ndk::EntityHandle& entity : *this) + entity->UnregisterEntityList(this); + + m_entityBits.Clear(); + m_world = nullptr; + } + + /*! + * \brief Checks whether or not the EntityList contains the entity * \return true If it is the case * * \param entity Pointer to the entity + * + * \remark If the Insert function was called since the EntityList construction (or last call to Clear), the entity passed by parameter must belong to the same world as the previously inserted entities. */ - - inline bool EntityList::Has(const Entity* entity) + inline bool EntityList::Has(const Entity* entity) const { + NazaraAssert(!m_world || !entity || entity->GetWorld() == m_world, "Incompatible world"); + return entity && entity->IsValid() && Has(entity->GetId()); } @@ -41,8 +89,7 @@ namespace Ndk * * \param id Identifier of the entity */ - - inline bool EntityList::Has(EntityId entity) + inline bool EntityList::Has(EntityId entity) const { return m_entityBits.UnboundedTest(entity); } @@ -50,17 +97,23 @@ namespace Ndk /*! * \brief Inserts the entity into the set * - * \param entity Pointer to the entity + * Marks an entity as present in this entity list, it must belongs to the same world as others entities contained in this list. + * + * \param entity Valid pointer to an entity * * \remark If entity is already contained, no action is performed + * \remark If any entity has been inserted since construction (or last Clear call), the entity must belong to the same world as the previously inserted entities */ - inline void EntityList::Insert(Entity* entity) { + NazaraAssert(entity, "Invalid entity"); + if (!Has(entity)) { - m_entities.emplace_back(entity); + entity->RegisterEntityList(this); + m_entityBits.UnboundedSet(entity->GetId(), true); + m_world = entity->GetWorld(); } } @@ -70,89 +123,138 @@ namespace Ndk * \param entity Pointer to the entity * * \remark If entity is not contained, no action is performed + * \remark This function never resets the implicit world member, even if it empties the list. Use the Clear method if you want to reset it. + * + * \see Clear */ - inline void EntityList::Remove(Entity* entity) { if (Has(entity)) { - auto it = std::find(m_entities.begin(), m_entities.end(), *entity); - NazaraAssert(it != m_entities.end(), "Entity should be part of the vector"); + m_entityBits.Reset(entity->GetId()); - std::swap(*it, m_entities.back()); - m_entities.pop_back(); // We get it out of the vector - m_entityBits.UnboundedSet(entity->GetId(), false); + entity->UnregisterEntityList(this); } } - // Nz::Interface STD - inline EntityList::Container::iterator EntityList::begin() + // STL Interface + inline EntityList::iterator EntityList::begin() const { - return m_entities.begin(); - } - - inline EntityList::Container::const_iterator EntityList::begin() const - { - return m_entities.begin(); - } - - inline EntityList::Container::const_iterator EntityList::cbegin() const - { - return m_entities.cbegin(); - } - - inline EntityList::Container::const_iterator EntityList::cend() const - { - return m_entities.cend(); - } - - inline EntityList::Container::const_reverse_iterator EntityList::crbegin() const - { - return m_entities.crbegin(); - } - - inline EntityList::Container::const_reverse_iterator EntityList::crend() const - { - return m_entities.crend(); + return EntityList::iterator(this, m_entityBits.FindFirst()); } inline bool EntityList::empty() const { - return m_entities.empty(); + return !m_entityBits.TestAny(); } - inline EntityList::Container::iterator EntityList::end() + inline EntityList::iterator EntityList::end() const { - return m_entities.end(); + return EntityList::iterator(this, m_entityBits.npos); } - inline EntityList::Container::const_iterator EntityList::end() const + inline EntityList::size_type EntityList::size() const { - return m_entities.end(); + return m_entityBits.Count(); } - inline EntityList::Container::reverse_iterator EntityList::rbegin() + inline EntityList& EntityList::operator=(const EntityList& entityList) { - return m_entities.rbegin(); + m_entityBits = entityList.m_entityBits; + m_world = entityList.m_world; + + for (const Ndk::EntityHandle& entity : *this) + entity->RegisterEntityList(this); + + return *this; } - inline EntityList::Container::const_reverse_iterator EntityList::rbegin() const + inline EntityList& EntityList::operator=(EntityList&& entityList) noexcept { - return m_entities.rbegin(); + m_entityBits = std::move(entityList.m_entityBits); + m_world = entityList.m_world; + + for (const Ndk::EntityHandle& entity : *this) + { + entity->UnregisterEntityList(&entityList); + entity->RegisterEntityList(this); + } + + return *this; } - inline EntityList::Container::reverse_iterator EntityList::rend() + inline std::size_t EntityList::FindNext(std::size_t currentId) const { - return m_entities.rend(); + return m_entityBits.FindNext(currentId); } - inline EntityList::Container::const_reverse_iterator EntityList::rend() const + inline World* EntityList::GetWorld() const { - return m_entities.rend(); + return m_world; } - inline EntityList::Container::size_type EntityList::size() const + inline void EntityList::NotifyEntityDestruction(const Entity* entity) { - return m_entities.size(); + assert(Has(entity)); + + m_entityBits.Reset(entity->GetId()); + } + + + inline EntityList::iterator::iterator(const EntityList* list, std::size_t nextId) : + m_nextEntityId(nextId), + m_list(list) + { + } + + inline EntityList::iterator::iterator(const iterator& it) : + m_nextEntityId(it.m_nextEntityId), + m_list(it.m_list) + { + } + + inline EntityList::iterator& EntityList::iterator::operator=(const iterator& it) + { + m_nextEntityId = it.m_nextEntityId; + m_list = it.m_list; + + return *this; + } + + inline EntityList::iterator& EntityList::iterator::operator++() + { + m_nextEntityId = m_list->FindNext(m_nextEntityId); + + return *this; + } + + inline EntityList::iterator EntityList::iterator::operator++(int) + { + std::size_t previousId = m_nextEntityId; + + m_nextEntityId = m_list->FindNext(m_nextEntityId); + + return iterator(m_list, previousId); + } + + inline bool operator==(const EntityList::iterator& lhs, const EntityList::iterator& rhs) + { + NazaraAssert(lhs.m_list == rhs.m_list, "Cannot compare iterator coming from different lists"); + + return lhs.m_nextEntityId == rhs.m_nextEntityId; + } + + inline bool operator!=(const EntityList::iterator& lhs, const EntityList::iterator& rhs) + { + return !operator==(lhs, rhs); + } + + inline void swap(EntityList::iterator& lhs, EntityList::iterator& rhs) + { + NazaraAssert(lhs.m_list == rhs.m_list, "Cannot compare iterator coming from different lists"); + + using std::swap; + + swap(lhs.m_nextEntityId, rhs.m_nextEntityId); } } diff --git a/SDK/include/NDK/EntityOwner.hpp b/SDK/include/NDK/EntityOwner.hpp index d0a4a4f59..9216b3d3c 100644 --- a/SDK/include/NDK/EntityOwner.hpp +++ b/SDK/include/NDK/EntityOwner.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/EntityOwner.inl b/SDK/include/NDK/EntityOwner.inl index 2cb64f1e8..7a7c94815 100644 --- a/SDK/include/NDK/EntityOwner.inl +++ b/SDK/include/NDK/EntityOwner.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Lua/LuaBinding.hpp b/SDK/include/NDK/Lua/LuaBinding.hpp index 307345589..c1ea9206d 100644 --- a/SDK/include/NDK/Lua/LuaBinding.hpp +++ b/SDK/include/NDK/Lua/LuaBinding.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -24,7 +24,7 @@ namespace Ndk template void BindComponent(const Nz::String& name); - void RegisterClasses(Nz::LuaInstance& instance); + void RegisterClasses(Nz::LuaState& state); std::unique_ptr core; std::unique_ptr math; @@ -40,13 +40,13 @@ namespace Ndk private: template - static int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle); + static int AddComponentOfType(Nz::LuaState& lua, EntityHandle& handle); template - static int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component); + static int PushComponentOfType(Nz::LuaState& lua, BaseComponent& component); - using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); - using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); + using AddComponentFunc = int(*)(Nz::LuaState&, EntityHandle&); + using GetComponentFunc = int(*)(Nz::LuaState&, BaseComponent&); struct ComponentBinding { @@ -56,7 +56,7 @@ namespace Ndk Nz::String name; }; - ComponentBinding* QueryComponentIndex(Nz::LuaInstance& lua, int argIndex = 2); + ComponentBinding* QueryComponentIndex(Nz::LuaState& lua, int argIndex = 2); std::vector m_componentBinding; std::unordered_map m_componentBindingByName; diff --git a/SDK/include/NDK/Lua/LuaBinding.inl b/SDK/include/NDK/Lua/LuaBinding.inl index ca77dfcf6..502f179ae 100644 --- a/SDK/include/NDK/Lua/LuaBinding.inl +++ b/SDK/include/NDK/Lua/LuaBinding.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -33,7 +33,7 @@ namespace Ndk } template - int LuaBinding::AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle) + int LuaBinding::AddComponentOfType(Nz::LuaState& lua, EntityHandle& handle) { static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); @@ -43,7 +43,7 @@ namespace Ndk } template - int LuaBinding::PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component) + int LuaBinding::PushComponentOfType(Nz::LuaState& lua, BaseComponent& component) { static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); diff --git a/SDK/include/NDK/Lua/LuaBinding_Audio.hpp b/SDK/include/NDK/Lua/LuaBinding_Audio.hpp index 510654342..d842ecc9b 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Audio.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Audio.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -21,7 +21,7 @@ namespace Ndk LuaBinding_Audio(LuaBinding& binding); ~LuaBinding_Audio() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass music; Nz::LuaClass sound; diff --git a/SDK/include/NDK/Lua/LuaBinding_Base.hpp b/SDK/include/NDK/Lua/LuaBinding_Base.hpp index 29c486835..8e596e999 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Base.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -30,7 +30,7 @@ namespace Ndk LuaBinding_Base(LuaBinding& binding); virtual ~LuaBinding_Base(); - virtual void Register(Nz::LuaInstance& instance) = 0; + virtual void Register(Nz::LuaState& state) = 0; // Implementation lies in the respective .cpp files (still searching for a cleaner way..) static std::unique_ptr BindCore(LuaBinding& binding); diff --git a/SDK/include/NDK/Lua/LuaBinding_Core.hpp b/SDK/include/NDK/Lua/LuaBinding_Core.hpp index 54400958f..decca39fc 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Core.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Core.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -21,7 +21,7 @@ namespace Ndk LuaBinding_Core(LuaBinding& binding); ~LuaBinding_Core() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass clock; Nz::LuaClass directory; diff --git a/SDK/include/NDK/Lua/LuaBinding_Graphics.hpp b/SDK/include/NDK/Lua/LuaBinding_Graphics.hpp index 75a6eff8f..cd71f0fc5 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Graphics.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Graphics.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -22,7 +22,7 @@ namespace Ndk LuaBinding_Graphics(LuaBinding& binding); ~LuaBinding_Graphics() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass abstractViewer; Nz::LuaClass instancedRenderable; diff --git a/SDK/include/NDK/Lua/LuaBinding_Math.hpp b/SDK/include/NDK/Lua/LuaBinding_Math.hpp index 195d34ec2..386912bab 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Math.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Math.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -23,7 +23,7 @@ namespace Ndk LuaBinding_Math(LuaBinding& binding); ~LuaBinding_Math() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass eulerAngles; Nz::LuaClass matrix4d; diff --git a/SDK/include/NDK/Lua/LuaBinding_Network.hpp b/SDK/include/NDK/Lua/LuaBinding_Network.hpp index f69e038a7..daee2b224 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Network.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Network.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace Ndk @@ -19,10 +20,11 @@ namespace Ndk LuaBinding_Network(LuaBinding& binding); ~LuaBinding_Network() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass abstractSocket; Nz::LuaClass ipAddress; + Nz::LuaClass udpSocket; }; } diff --git a/SDK/include/NDK/Lua/LuaBinding_Renderer.hpp b/SDK/include/NDK/Lua/LuaBinding_Renderer.hpp index 7655c9ac3..af1ffeaa5 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Renderer.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Renderer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -18,7 +18,7 @@ namespace Ndk LuaBinding_Renderer(LuaBinding& binding); ~LuaBinding_Renderer() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass texture; Nz::LuaClass textureLibrary; diff --git a/SDK/include/NDK/Lua/LuaBinding_SDK.hpp b/SDK/include/NDK/Lua/LuaBinding_SDK.hpp index facfd5620..8a6a0915e 100644 --- a/SDK/include/NDK/Lua/LuaBinding_SDK.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_SDK.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -22,7 +22,7 @@ namespace Ndk LuaBinding_SDK(LuaBinding& binding); ~LuaBinding_SDK() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; Nz::LuaClass application; Nz::LuaClass entity; diff --git a/SDK/include/NDK/Lua/LuaBinding_Utility.hpp b/SDK/include/NDK/Lua/LuaBinding_Utility.hpp index 80afde5bf..8aefd20c6 100644 --- a/SDK/include/NDK/Lua/LuaBinding_Utility.hpp +++ b/SDK/include/NDK/Lua/LuaBinding_Utility.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -21,7 +21,7 @@ namespace Ndk LuaBinding_Utility(LuaBinding& binding); ~LuaBinding_Utility() = default; - void Register(Nz::LuaInstance& instance) override; + void Register(Nz::LuaState& state) override; // Utility Nz::LuaClass abstractImage; diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index bc4631e47..d3e755fc6 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -11,7 +11,7 @@ namespace Nz { - class LuaInstance; + class LuaState; } namespace Ndk @@ -28,7 +28,7 @@ namespace Ndk static bool Initialize(); - static void RegisterClasses(Nz::LuaInstance& instance); + static void RegisterClasses(Nz::LuaState& state); static void Uninitialize(); diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 6b7573597..84e3fb34e 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -1,10 +1,10 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include #include -#include +#include #include #include #include @@ -28,103 +28,103 @@ namespace Nz { - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Color* color, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Color* color, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.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); + color->r = state.CheckField("r", index); + color->g = state.CheckField("g", index); + color->b = state.CheckField("b", index); + color->a = state.CheckField("a", 255, index); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, EulerAnglesd* angles, TypeTag) { - switch (instance.GetType(index)) + switch (state.GetType(index)) { case Nz::LuaType_Table: - angles->Set(instance.CheckField("pitch", index), instance.CheckField("yaw", index), instance.CheckField("roll", index)); + angles->Set(state.CheckField("pitch", index), state.CheckField("yaw", index), state.CheckField("roll", index)); return 1; default: { - if (instance.IsOfType(index, "EulerAngles")) - angles->Set(*static_cast(instance.ToUserdata(index))); + if (state.IsOfType(index, "EulerAngles")) + angles->Set(*static_cast(state.ToUserdata(index))); else - angles->Set(*static_cast(instance.CheckUserdata(index, "Quaternion"))); + angles->Set(*static_cast(state.CheckUserdata(index, "Quaternion"))); return 1; } } } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesf* angles, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, EulerAnglesf* angles, TypeTag) { EulerAnglesd anglesDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &anglesDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &anglesDouble, TypeTag()); angles->Set(anglesDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontRef* fontRef, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, FontRef* fontRef, TypeTag) { - *fontRef = *static_cast(instance.CheckUserdata(index, "Font")); + *fontRef = *static_cast(state.CheckUserdata(index, "Font")); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, FontParams* params, TypeTag) { NazaraUnused(params); - instance.CheckType(index, Nz::LuaType_Table); + state.CheckType(index, Nz::LuaType_Table); // Structure is empty for now return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ImageParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, ImageParams* params, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.CheckType(index, Nz::LuaType_Table); - params->levelCount = instance.CheckField("LevelCount"); - params->loadFormat = instance.CheckField("LoadFormat"); + params->levelCount = state.CheckField("LevelCount"); + params->loadFormat = state.CheckField("LoadFormat"); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, IpAddress* address, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, IpAddress* address, TypeTag) { - switch (instance.GetType(index)) + switch (state.GetType(index)) { case Nz::LuaType_String: - address->BuildFromAddress(instance.CheckString(index)); + address->BuildFromAddress(state.CheckString(index)); return 1; default: - *address = *static_cast(instance.CheckUserdata(index, "IpAddress")); + *address = *static_cast(state.CheckUserdata(index, "IpAddress")); return 1; } } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Matrix4d* mat, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Matrix4d* mat, TypeTag) { - switch (instance.GetType(index)) + switch (state.GetType(index)) { case Nz::LuaType_Table: { double values[16]; for (std::size_t i = 0; i < 16; ++i) { - instance.PushInteger(i + 1); - instance.GetTable(); + state.PushInteger(i + 1); + state.GetTable(); - values[i] = instance.CheckNumber(-1); - instance.Pop(); + values[i] = state.CheckNumber(-1); + state.Pop(); } mat->Set(values); @@ -133,500 +133,500 @@ namespace Nz default: { - if (instance.IsOfType(index, "Matrix4")) - mat->Set(*static_cast(instance.ToUserdata(index))); + if (state.IsOfType(index, "Matrix4")) + mat->Set(*static_cast(state.ToUserdata(index))); return 1; } } } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Matrix4f* mat, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Matrix4f* mat, TypeTag) { Matrix4d matDouble = Matrix4d::Identity(); - unsigned int ret = LuaImplQueryArg(instance, index, &matDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &matDouble, TypeTag()); mat->Set(matDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MeshParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MeshParams* params, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.CheckType(index, Nz::LuaType_Table); - params->animated = instance.CheckField("Animated", params->animated); - params->center = instance.CheckField("Center", params->center); - params->matrix = instance.CheckField("Matrix", params->matrix); - params->optimizeIndexBuffers = instance.CheckField("OptimizeIndexBuffers", params->optimizeIndexBuffers); - params->texCoordOffset = instance.CheckField("TexCoordOffset", params->texCoordOffset); - params->texCoordScale = instance.CheckField("TexCoordScale", params->texCoordScale); + params->animated = state.CheckField("Animated", params->animated); + params->center = state.CheckField("Center", params->center); + params->matrix = state.CheckField("Matrix", params->matrix); + params->optimizeIndexBuffers = state.CheckField("OptimizeIndexBuffers", params->optimizeIndexBuffers); + params->texCoordOffset = state.CheckField("TexCoordOffset", params->texCoordOffset); + params->texCoordScale = state.CheckField("TexCoordScale", params->texCoordScale); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaterniond* quat, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Quaterniond* quat, TypeTag) { - switch (instance.GetType(index)) + switch (state.GetType(index)) { case Nz::LuaType_Table: - quat->Set(instance.CheckField("w", index), instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", index)); + quat->Set(state.CheckField("w", index), state.CheckField("x", index), state.CheckField("y", index), state.CheckField("z", index)); return 1; default: { - if (instance.IsOfType(index, "EulerAngles")) - quat->Set(*static_cast(instance.ToUserdata(index))); + if (state.IsOfType(index, "EulerAngles")) + quat->Set(*static_cast(state.ToUserdata(index))); else - quat->Set(*static_cast(instance.CheckUserdata(index, "Quaternion"))); + quat->Set(*static_cast(state.CheckUserdata(index, "Quaternion"))); return 1; } } } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaternionf* quat, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Quaternionf* quat, TypeTag) { Quaterniond quatDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &quatDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &quatDouble, TypeTag()); quat->Set(quatDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectd* rect, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Rectd* rect, TypeTag) { - instance.CheckType(index, LuaType_Table); + state.CheckType(index, LuaType_Table); - rect->x = instance.CheckField("x", index); - rect->y = instance.CheckField("y", index); - rect->width = instance.CheckField("width", index); - rect->height = instance.CheckField("height", index); + rect->x = state.CheckField("x", index); + rect->y = state.CheckField("y", index); + rect->width = state.CheckField("width", index); + rect->height = state.CheckField("height", index); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectf* rect, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Rectf* rect, TypeTag) { Rectd rectDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &rectDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &rectDouble, TypeTag()); rect->Set(rectDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Recti* rect, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Recti* rect, TypeTag) { Rectd rectDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &rectDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &rectDouble, TypeTag()); rect->Set(rectDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectui* rect, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Rectui* rect, TypeTag) { Rectd rectDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &rectDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &rectDouble, TypeTag()); rect->Set(rectDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2d* vec, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector2d* vec, TypeTag) { - switch (instance.GetType(index)) + switch (state.GetType(index)) { case Nz::LuaType_Number: if (index < 0 && index > -2) - instance.Error("Vector2 expected, two numbers are required to convert it"); + state.Error("Vector2 expected, two numbers are required to convert it"); - vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1)); + vec->Set(state.CheckNumber(index), state.CheckNumber(index + 1)); return 2; case Nz::LuaType_Table: - vec->Set(instance.CheckField("x", index), instance.CheckField("y", index)); + vec->Set(state.CheckField("x", index), state.CheckField("y", index)); return 1; default: - vec->Set(*static_cast(instance.CheckUserdata(index, "Vector2"))); + vec->Set(*static_cast(state.CheckUserdata(index, "Vector2"))); return 1; } } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2f* vec, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector2f* vec, TypeTag) { Vector2d vecDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag()); vec->Set(vecDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2ui* vec, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector2ui* vec, TypeTag) { Vector2d vecDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag()); vec->Set(vecDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3d* vec, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector3d* vec, TypeTag) { - switch (instance.GetType(index)) + switch (state.GetType(index)) { case Nz::LuaType_Number: if (index < 0 && index > -3) - instance.Error("Vector3 expected, three numbers are required to convert it"); + state.Error("Vector3 expected, three numbers are required to convert it"); - vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1), instance.CheckNumber(index + 2, 0.0)); + vec->Set(state.CheckNumber(index), state.CheckNumber(index + 1), state.CheckNumber(index + 2, 0.0)); return 3; case Nz::LuaType_Table: - vec->Set(instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", 0.0, index)); + vec->Set(state.CheckField("x", index), state.CheckField("y", index), state.CheckField("z", 0.0, index)); return 1; default: - vec->Set(*static_cast(instance.CheckUserdata(index, "Vector3"))); + vec->Set(*static_cast(state.CheckUserdata(index, "Vector3"))); return 1; } } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3f* vec, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector3f* vec, TypeTag) { Vector3d vecDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag()); vec->Set(vecDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3ui* vec, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector3ui* vec, TypeTag) { Vector3d vecDouble; - unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag()); vec->Set(vecDouble); return ret; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Ndk::EntityHandle* handle, TypeTag) { - *handle = *static_cast(instance.CheckUserdata(index, "Entity")); + *handle = *static_cast(state.CheckUserdata(index, "Entity")); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Ndk::WorldHandle* handle, TypeTag) { - *handle = *static_cast(instance.CheckUserdata(index, "World")); + *handle = *static_cast(state.CheckUserdata(index, "World")); return 1; } #ifndef NDK_SERVER - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, InstancedRenderableRef* renderable, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, InstancedRenderableRef* renderable, TypeTag) { - if (instance.IsOfType(index, "InstancedRenderable") || - instance.IsOfType(index, "Model") || - instance.IsOfType(index, "Sprite")) + if (state.IsOfType(index, "InstancedRenderable") || + state.IsOfType(index, "Model") || + state.IsOfType(index, "Sprite")) { - *renderable = *static_cast(instance.ToUserdata(index)); + *renderable = *static_cast(state.ToUserdata(index)); } else - instance.ArgError(index, "is not a InstancedRenderable instance"); + state.ArgError(index, "is not a InstancedRenderable instance"); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialRef* materialRef, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MaterialRef* materialRef, TypeTag) { - *materialRef = *static_cast(instance.CheckUserdata(index, "Material")); + *materialRef = *static_cast(state.CheckUserdata(index, "Material")); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MaterialParams* params, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.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); - params->shaderName = instance.CheckField("ShaderName", params->shaderName); + params->loadAlphaMap = state.CheckField("LoadAlphaMap", params->loadAlphaMap); + params->loadDiffuseMap = state.CheckField("LoadDiffuseMap", params->loadDiffuseMap); + params->loadEmissiveMap = state.CheckField("LoadEmissiveMap", params->loadEmissiveMap); + params->loadHeightMap = state.CheckField("LoadHeightMap", params->loadHeightMap); + params->loadNormalMap = state.CheckField("LoadNormalMap", params->loadNormalMap); + params->loadSpecularMap = state.CheckField("LoadSpecularMap", params->loadSpecularMap); + params->shaderName = state.CheckField("ShaderName", params->shaderName); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ModelParameters* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, ModelParameters* params, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.CheckType(index, Nz::LuaType_Table); - params->loadMaterials = instance.CheckField("LoadMaterials", params->loadMaterials); + params->loadMaterials = state.CheckField("LoadMaterials", params->loadMaterials); - LuaImplQueryArg(instance, -1, ¶ms->material, TypeTag()); - LuaImplQueryArg(instance, -1, ¶ms->mesh, TypeTag()); + LuaImplQueryArg(state, -1, ¶ms->material, TypeTag()); + LuaImplQueryArg(state, -1, ¶ms->mesh, TypeTag()); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MusicParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MusicParams* params, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.CheckType(index, Nz::LuaType_Table); - params->forceMono = instance.CheckField("ForceMono", params->forceMono); + params->forceMono = state.CheckField("ForceMono", params->forceMono); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SoundBufferParams* params, TypeTag) { - instance.CheckType(index, Nz::LuaType_Table); + state.CheckType(index, Nz::LuaType_Table); - params->forceMono = instance.CheckField("ForceMono", params->forceMono); + params->forceMono = state.CheckField("ForceMono", params->forceMono); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SpriteRef* spriteRef, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SpriteRef* spriteRef, TypeTag) { - *spriteRef = *static_cast(instance.CheckUserdata(index, "Sprite")); + *spriteRef = *static_cast(state.CheckUserdata(index, "Sprite")); return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, TextureRef* textureRef, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, TextureRef* textureRef, TypeTag) { - *textureRef = *static_cast(instance.CheckUserdata(index, "Texture")); + *textureRef = *static_cast(state.CheckUserdata(index, "Texture")); return 1; } #endif - inline int LuaImplReplyVal(const LuaInstance& instance, Color&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Color&& val, TypeTag) { - instance.PushTable(); - instance.PushField("r", val.r); - instance.PushField("g", val.g); - instance.PushField("b", val.b); - instance.PushField("a", val.a); + state.PushTable(); + state.PushField("r", val.r); + state.PushField("g", val.g); + state.PushField("b", val.b); + state.PushField("a", val.a); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesd&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, EulerAnglesd&& val, TypeTag) { - instance.PushInstance("EulerAngles", val); + state.PushInstance("EulerAngles", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesf&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, EulerAnglesf&& val, TypeTag) { - instance.PushInstance("EulerAngles", val); + state.PushInstance("EulerAngles", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, FontRef&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, FontRef&& val, TypeTag) { - instance.PushInstance("Font", val); + state.PushInstance("Font", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Font::SizeInfo&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Font::SizeInfo&& val, TypeTag) { - instance.PushTable(); - instance.PushField("LineHeight", val.lineHeight); - instance.PushField("SpaceAdvance", val.spaceAdvance); - instance.PushField("UnderlinePosition", val.underlinePosition); - instance.PushField("UnderlineThickness", val.underlineThickness); + state.PushTable(); + state.PushField("LineHeight", val.lineHeight); + state.PushField("SpaceAdvance", val.spaceAdvance); + state.PushField("UnderlinePosition", val.underlinePosition); + state.PushField("UnderlineThickness", val.underlineThickness); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, ImageParams&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, ImageParams&& val, TypeTag) { - instance.PushTable(0, 2); - instance.PushField("LevelCount", val.levelCount); - instance.PushField("LoadFormat", val.loadFormat); + state.PushTable(0, 2); + state.PushField("LevelCount", val.levelCount); + state.PushField("LoadFormat", val.loadFormat); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, IpAddress&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, IpAddress&& val, TypeTag) { - instance.PushInstance("IpAddress", val); + state.PushInstance("IpAddress", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Matrix4d&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Matrix4d&& val, TypeTag) { - instance.PushInstance("Matrix4", val); + state.PushInstance("Matrix4", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Matrix4f&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Matrix4f&& val, TypeTag) { - instance.PushInstance("Matrix4", val); + state.PushInstance("Matrix4", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Quaterniond&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Quaterniond&& val, TypeTag) { - instance.PushInstance("Quaternion", val); + state.PushInstance("Quaternion", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Quaternionf&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Quaternionf&& val, TypeTag) { - instance.PushInstance("Quaternion", val); + state.PushInstance("Quaternion", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Rectd&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Rectd&& val, TypeTag) { - instance.PushInstance("Rect", val); + state.PushInstance("Rect", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Rectf&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Rectf&& val, TypeTag) { - instance.PushInstance("Rect", val); + state.PushInstance("Rect", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Recti&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Recti&& val, TypeTag) { - instance.PushInstance("Rect", val); + state.PushInstance("Rect", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Rectui&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Rectui&& val, TypeTag) { - instance.PushInstance("Rect", val); + state.PushInstance("Rect", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Vector2d&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Vector2d&& val, TypeTag) { - instance.PushInstance("Vector2", val); + state.PushInstance("Vector2", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Vector2f&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Vector2f&& val, TypeTag) { - instance.PushInstance("Vector2", val); + state.PushInstance("Vector2", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Vector2ui&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Vector2ui&& val, TypeTag) { - instance.PushInstance("Vector2", val); + state.PushInstance("Vector2", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Vector3d&& val, TypeTag) { - instance.PushInstance("Vector3", val); + state.PushInstance("Vector3", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Vector3f&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Vector3f&& val, TypeTag) { - instance.PushInstance("Vector3", val); + state.PushInstance("Vector3", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Vector3ui&& val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Vector3ui&& val, TypeTag) { - instance.PushInstance("Vector3", val); + state.PushInstance("Vector3", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Entity* ptr, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::Entity* ptr, TypeTag) { - instance.PushInstance("Entity", ptr); + state.PushInstance("Entity", ptr); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Application* ptr, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::Application* ptr, TypeTag) { - instance.PushInstance("Application", ptr); + state.PushInstance("Application", ptr); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::EntityHandle&& handle, TypeTag) { - instance.PushInstance("Entity", handle); + state.PushInstance("Entity", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::NodeComponentHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::NodeComponentHandle&& handle, TypeTag) { - instance.PushInstance("NodeComponent", handle); + state.PushInstance("NodeComponent", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::VelocityComponentHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::VelocityComponentHandle&& handle, TypeTag) { - instance.PushInstance("VelocityComponent", handle); + state.PushInstance("VelocityComponent", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::World* ptr, TypeTag) { - instance.PushInstance("World", ptr); + state.PushInstance("World", ptr); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::WorldHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::WorldHandle&& handle, TypeTag) { - instance.PushInstance("World", handle); + state.PushInstance("World", handle); return 1; } #ifndef NDK_SERVER - inline int LuaImplReplyVal(const LuaInstance& instance, MaterialRef&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, MaterialRef&& handle, TypeTag) { - instance.PushInstance("Material", handle); + state.PushInstance("Material", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, const SoundBuffer* val, TypeTag) { - instance.PushInstance("SoundBuffer", val); + state.PushInstance("SoundBuffer", val); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, SpriteRef&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, SpriteRef&& handle, TypeTag) { - instance.PushInstance("Sprite", handle); + state.PushInstance("Sprite", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, TextureRef&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, TextureRef&& handle, TypeTag) { - instance.PushInstance("Texture", handle); + state.PushInstance("Texture", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::CameraComponentHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::CameraComponentHandle&& handle, TypeTag) { - instance.PushInstance("CameraComponent", handle); + state.PushInstance("CameraComponent", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::ConsoleHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::ConsoleHandle&& handle, TypeTag) { - instance.PushInstance("Console", handle); + state.PushInstance("Console", handle); return 1; } - inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle&& handle, TypeTag) + inline int LuaImplReplyVal(const LuaState& state, Ndk::GraphicsComponentHandle&& handle, TypeTag) { - instance.PushInstance("GraphicsComponent", handle); + state.PushInstance("GraphicsComponent", handle); return 1; } #endif diff --git a/SDK/include/NDK/Sdk.hpp b/SDK/include/NDK/Sdk.hpp index 7883162ea..5b976d1eb 100644 --- a/SDK/include/NDK/Sdk.hpp +++ b/SDK/include/NDK/Sdk.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Sdk.inl b/SDK/include/NDK/Sdk.inl index 3cbafab66..de2bb8043 100644 --- a/SDK/include/NDK/Sdk.inl +++ b/SDK/include/NDK/Sdk.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/State.hpp b/SDK/include/NDK/State.hpp index 621227fbe..cc8155ccf 100644 --- a/SDK/include/NDK/State.hpp +++ b/SDK/include/NDK/State.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/StateMachine.hpp b/SDK/include/NDK/StateMachine.hpp index c36464fea..e9e665c44 100644 --- a/SDK/include/NDK/StateMachine.hpp +++ b/SDK/include/NDK/StateMachine.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace Ndk { @@ -25,14 +26,21 @@ namespace Ndk inline const std::shared_ptr& GetCurrentState() const; + inline bool IsTopState(const State* state) const; + + inline std::shared_ptr PopState(); + inline bool PopStatesUntil(std::shared_ptr state); + inline void PushState(std::shared_ptr state); + + inline void SetState(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; + std::vector> m_states; }; } diff --git a/SDK/include/NDK/StateMachine.inl b/SDK/include/NDK/StateMachine.inl index c522f5431..1086df54d 100644 --- a/SDK/include/NDK/StateMachine.inl +++ b/SDK/include/NDK/StateMachine.inl @@ -1,9 +1,8 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include #include namespace Ndk @@ -11,7 +10,7 @@ namespace Ndk /*! * \ingroup NDK * \class Ndk::StateMachine - * \brief NDK class that represents a state machine, to represent the multiple states of your program + * \brief NDK class that represents a state machine, to represent the multiple states of your program as a stack */ /*! @@ -23,61 +22,153 @@ namespace Ndk * \remark Produces a NazaraAssert if nullptr is given */ - inline StateMachine::StateMachine(std::shared_ptr originalState) : - m_currentState(std::move(originalState)) + inline StateMachine::StateMachine(std::shared_ptr originalState) { - NazaraAssert(m_currentState, "StateMachine must have a state to begin with"); - m_currentState->Enter(*this); + NazaraAssert(originalState, "StateMachine must have a state to begin with"); + PushState(std::move(originalState)); } /*! * \brief Destructs the object * - * \remark Calls "Leave" on the state + * \remark Calls "Leave" on all the states */ inline StateMachine::~StateMachine() { - m_currentState->Leave(*this); + for (std::shared_ptr& state : m_states) + state->Leave(*this); } /*! - * \brief Changes the current state of the machine + * \brief Replaces the current state on the top of the machine * - * \param state Next state to represent + * \param state State to replace the top one if it is nullptr, no action is performed */ inline void StateMachine::ChangeState(std::shared_ptr state) { - m_nextState = std::move(state); + if (state) + { + PopState(); + PushState(std::move(state)); + } } /*! - * \brief Gets the current state of the machine + * \brief Gets the current state on the top of the machine * \return A constant reference to the state + * + * \remark The stack is supposed to be non empty, otherwise it is undefined behaviour + * + * \see PopStatesUntil */ inline const std::shared_ptr& StateMachine::GetCurrentState() const { - return m_currentState; + return m_states.back(); } /*! - * \brief Updates the state - * \return True if update is successful + * \brief Checks whether the state is on the top of the machine + * \return true If it is the case + * + * \param state State to compare the top with + */ + + inline bool StateMachine::IsTopState(const State* state) const + { + if (m_states.empty()) + return false; + + return m_states.back().get() == state; + } + + /*! + * \brief Pops the state on the top of the machine + * \return Old state on the top, nullptr if stack was empty + * + * \remark This method can completely empty the stack + */ + + inline std::shared_ptr StateMachine::PopState() + { + if (m_states.empty()) + return nullptr; + + m_states.back()->Leave(*this); + std::shared_ptr oldTopState = std::move(m_states.back()); + m_states.pop_back(); + return oldTopState; + } + + /*! + * \brief Pops all the states of the machine until a specific one is reached + * \return true If that specific state is on top, false if stack is empty + * + * \param state State to find on the stack if it is nullptr, no action is performed + * + * \remark This method can completely empty the stack + */ + + inline bool StateMachine::PopStatesUntil(std::shared_ptr state) + { + if (!state) + return false; + + while (!m_states.empty() && !IsTopState(state.get())) + PopState(); + + return !m_states.empty(); + } + + /*! + * \brief Pushes a new state on the top of the machine + * + * \param state Next state to represent if it is nullptr, it performs no action + * + * \remark Produces a NazaraAssert if the same state is pushed two times on the stack + */ + + inline void StateMachine::PushState(std::shared_ptr state) + { + if (state) + { + NazaraAssert(std::find(m_states.begin(), m_states.end(), state) == m_states.end(), "The same state was pushed two times"); + + m_states.push_back(std::move(state)); + m_states.back()->Enter(*this); + } + } + + /*! + * \brief Pops every states of the machine to put a new one + * + * \param state State to reset the stack with if it is nullptr, no action is performed + */ + + inline void StateMachine::SetState(std::shared_ptr state) + { + if (state) + { + while (!m_states.empty()) + PopState(); + + PushState(std::move(state)); + } + } + + /*! + * \brief Updates all the states + * \return true If update is successful for everyone of them * * \param elapsedTime Delta time used for the update */ inline bool StateMachine::Update(float elapsedTime) { - if (m_nextState) - { - m_currentState->Leave(*this); - m_currentState = std::move(m_nextState); - m_currentState->Enter(*this); - } - - return m_currentState->Update(*this, elapsedTime); + return std::all_of(m_states.begin(), m_states.end(), [=](std::shared_ptr& state) { + return state->Update(*this, elapsedTime); + }); } } diff --git a/SDK/include/NDK/System.hpp b/SDK/include/NDK/System.hpp index b5a50f76f..935362763 100644 --- a/SDK/include/NDK/System.hpp +++ b/SDK/include/NDK/System.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/System.inl b/SDK/include/NDK/System.inl index d0359cc63..b3927d145 100644 --- a/SDK/include/NDK/System.inl +++ b/SDK/include/NDK/System.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/ListenerSystem.hpp b/SDK/include/NDK/Systems/ListenerSystem.hpp index bb166a4c1..290700284 100644 --- a/SDK/include/NDK/Systems/ListenerSystem.hpp +++ b/SDK/include/NDK/Systems/ListenerSystem.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/ListenerSystem.inl b/SDK/include/NDK/Systems/ListenerSystem.inl index e5f296d27..e555b080e 100644 --- a/SDK/include/NDK/Systems/ListenerSystem.inl +++ b/SDK/include/NDK/Systems/ListenerSystem.inl @@ -1,3 +1,3 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/ParticleSystem.hpp b/SDK/include/NDK/Systems/ParticleSystem.hpp index 61149b206..950ec80c9 100644 --- a/SDK/include/NDK/Systems/ParticleSystem.hpp +++ b/SDK/include/NDK/Systems/ParticleSystem.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/ParticleSystem.inl b/SDK/include/NDK/Systems/ParticleSystem.inl index e5f296d27..e555b080e 100644 --- a/SDK/include/NDK/Systems/ParticleSystem.inl +++ b/SDK/include/NDK/Systems/ParticleSystem.inl @@ -1,3 +1,3 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/PhysicsSystem2D.hpp b/SDK/include/NDK/Systems/PhysicsSystem2D.hpp index 31426450a..a117abaee 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem2D.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/PhysicsSystem2D.inl b/SDK/include/NDK/Systems/PhysicsSystem2D.inl index 21a34a6d4..1199d8830 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem2D.inl +++ b/SDK/include/NDK/Systems/PhysicsSystem2D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/PhysicsSystem3D.hpp b/SDK/include/NDK/Systems/PhysicsSystem3D.hpp index 35194b7c8..9d653695a 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem3D.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/PhysicsSystem3D.inl b/SDK/include/NDK/Systems/PhysicsSystem3D.inl index b6b1cbb03..3ea4b6be2 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem3D.inl +++ b/SDK/include/NDK/Systems/PhysicsSystem3D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 61ccefe75..a74cb9d0e 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -57,7 +57,7 @@ namespace Ndk std::unique_ptr m_renderTechnique; std::vector m_volumeEntries; - EntityList m_cameras; + std::vector m_cameras; EntityList m_drawables; EntityList m_directionalLights; EntityList m_lights; diff --git a/SDK/include/NDK/Systems/RenderSystem.inl b/SDK/include/NDK/Systems/RenderSystem.inl index 4b758aa92..8a443f993 100644 --- a/SDK/include/NDK/Systems/RenderSystem.inl +++ b/SDK/include/NDK/Systems/RenderSystem.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/VelocitySystem.hpp b/SDK/include/NDK/Systems/VelocitySystem.hpp index 71edcbe7e..d46eb7678 100644 --- a/SDK/include/NDK/Systems/VelocitySystem.hpp +++ b/SDK/include/NDK/Systems/VelocitySystem.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/VelocitySystem.inl b/SDK/include/NDK/Systems/VelocitySystem.inl index e5f296d27..e555b080e 100644 --- a/SDK/include/NDK/Systems/VelocitySystem.inl +++ b/SDK/include/NDK/Systems/VelocitySystem.inl @@ -1,3 +1,3 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Widgets/ButtonWidget.hpp b/SDK/include/NDK/Widgets/ButtonWidget.hpp index e2173d17e..8f2231501 100644 --- a/SDK/include/NDK/Widgets/ButtonWidget.hpp +++ b/SDK/include/NDK/Widgets/ButtonWidget.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -27,7 +27,7 @@ namespace Ndk //virtual ButtonWidget* Clone() const = 0; - void ResizeToContent(); + void ResizeToContent() override; inline void UpdateText(const Nz::AbstractTextDrawer& drawer); @@ -40,7 +40,6 @@ namespace Ndk void Layout() override; void OnMouseEnter() override; - void OnMouseMoved(int x, int y, int deltaX, int deltaY) override; void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) override; void OnMouseExit() override; diff --git a/SDK/include/NDK/Widgets/ButtonWidget.inl b/SDK/include/NDK/Widgets/ButtonWidget.inl index 92d40719a..fedc7614a 100644 --- a/SDK/include/NDK/Widgets/ButtonWidget.inl +++ b/SDK/include/NDK/Widgets/ButtonWidget.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Widgets/LabelWidget.hpp b/SDK/include/NDK/Widgets/LabelWidget.hpp index 736cfd650..06f53273c 100644 --- a/SDK/include/NDK/Widgets/LabelWidget.hpp +++ b/SDK/include/NDK/Widgets/LabelWidget.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Widgets/LabelWidget.inl b/SDK/include/NDK/Widgets/LabelWidget.inl index 4d4e100ce..a2d5d891f 100644 --- a/SDK/include/NDK/Widgets/LabelWidget.inl +++ b/SDK/include/NDK/Widgets/LabelWidget.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 8236b1689..0bf5a3a59 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -35,6 +35,7 @@ namespace Ndk inline std::size_t GetCursorPosition() const; inline std::size_t GetLineCount() const; inline const Nz::String& GetText() const; + inline const Nz::Color& GetTextColor() const; std::size_t GetHoveredGlyph(float x, float y) const; @@ -47,15 +48,24 @@ namespace Ndk inline void SetCursorPosition(std::size_t cursorPosition); inline void SetReadOnly(bool readOnly = true); - void SetText(const Nz::String& text); + inline void SetText(const Nz::String& text); + inline void SetTextColor(const Nz::Color& text); void Write(const Nz::String& text); TextAreaWidget& operator=(const TextAreaWidget&) = delete; TextAreaWidget& operator=(TextAreaWidget&&) = default; + NazaraSignal(OnTextAreaCursorMove, const TextAreaWidget* /*textArea*/, std::size_t* /*newCursorPosition*/); + NazaraSignal(OnTextAreaKeyBackspace, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextAreaKeyDown, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextAreaKeyLeft, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextAreaKeyReturn, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextAreaKeyRight, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextAreaKeyUp, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + private: - void RefreshCursor(); + void Layout() override; void OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) override; void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key) override; @@ -65,6 +75,8 @@ namespace Ndk void OnMouseExit() override; void OnTextEntered(char32_t character, bool repeated) override; + void RefreshCursor(); + EntityHandle m_cursorEntity; EntityHandle m_textEntity; Nz::SimpleTextDrawer m_drawer; diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index d923e7223..077f538ec 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -35,6 +35,11 @@ namespace Ndk return m_drawer.GetText(); } + inline const Nz::Color& TextAreaWidget::GetTextColor() const + { + return m_drawer.GetColor(); + } + inline bool Ndk::TextAreaWidget::IsMultilineEnabled() const { return m_multiLineEnabled; @@ -61,6 +66,8 @@ namespace Ndk inline void TextAreaWidget::SetCursorPosition(std::size_t cursorPosition) { + OnTextAreaCursorMove(this, &cursorPosition); + m_cursorPosition = std::min(cursorPosition, m_drawer.GetGlyphCount()); RefreshCursor(); @@ -72,4 +79,20 @@ namespace Ndk m_cursorEntity->Enable(!m_readOnly); } + + inline void TextAreaWidget::SetText(const Nz::String& text) + { + m_drawer.SetText(text); + + m_textSprite->Update(m_drawer); + + SetCursorPosition(m_cursorPosition); //< Refresh cursor position (prevent it from being outside of the text) + } + + inline void TextAreaWidget::SetTextColor(const Nz::Color& text) + { + m_drawer.SetColor(text); + + m_textSprite->Update(m_drawer); + } } diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index 5e819e517..29b9a4a9e 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ namespace Ndk friend Entity; public: - using EntityList = std::vector; + using EntityVector = std::vector; inline World(bool addDefaultSystems = true); World(const World&) = delete; @@ -41,21 +42,21 @@ namespace Ndk template SystemType& AddSystem(Args&&... args); const EntityHandle& CreateEntity(); - inline EntityList CreateEntities(unsigned int count); + inline EntityVector CreateEntities(unsigned int count); void Clear() noexcept; const EntityHandle& CloneEntity(EntityId id); - const EntityHandle& GetEntity(EntityId id); - inline const EntityList& GetEntities(); + inline const EntityHandle& GetEntity(EntityId id); + inline const EntityList& GetEntities() const; inline BaseSystem& GetSystem(SystemIndex index); template SystemType& GetSystem(); inline bool HasSystem(SystemIndex index) const; template bool HasSystem() const; - void KillEntity(Entity* entity); - inline void KillEntities(const EntityList& list); + inline void KillEntity(Entity* entity); + inline void KillEntities(const EntityVector& list); inline bool IsEntityValid(const Entity* entity) const; inline bool IsEntityIdValid(EntityId id) const; @@ -79,19 +80,22 @@ namespace Ndk struct EntityBlock { EntityBlock(Entity&& e) : - entity(std::move(e)) + entity(std::move(e)), + handle(&entity) { } EntityBlock(EntityBlock&& block) = default; Entity entity; - std::size_t aliveIndex; + EntityHandle handle; }; std::vector> m_systems; std::vector m_orderedSystems; std::vector m_entities; + std::vector m_entityBlocks; + std::vector> m_waitingEntities; std::vector m_freeIdList; EntityList m_aliveEntities; Nz::Bitset m_dirtyEntities; diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index 212038625..d45f0ff1d 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -82,9 +82,9 @@ namespace Ndk * \param count Number of entities to create */ - inline World::EntityList World::CreateEntities(unsigned int count) + inline World::EntityVector World::CreateEntities(unsigned int count) { - EntityList list; + EntityVector list; list.reserve(count); for (unsigned int i = 0; i < count; ++i) @@ -98,7 +98,7 @@ namespace Ndk * \return A constant reference to the entities */ - inline const World::EntityList& World::GetEntities() + inline const EntityList& World::GetEntities() const { return m_aliveEntities; } @@ -164,18 +164,53 @@ namespace Ndk return HasSystem(index); } + /*! + * \brief Marks an entity for deletion + * + * \param Pointer to the entity + * + * \remark If the entity pointer is invalid, nothing is done + * \remark For safety, entities are not killed until the next world update + */ + inline void World::KillEntity(Entity* entity) + { + if (IsEntityValid(entity)) + m_killedEntities.UnboundedSet(entity->GetId(), true); + } + /*! * \brief Kills a set of entities * + * This function has the same effect as calling KillEntity for every entity contained in the vector + * * \param list Set of entities to kill */ - - inline void World::KillEntities(const EntityList& list) + inline void World::KillEntities(const EntityVector& list) { for (const EntityHandle& entity : list) KillEntity(entity); } + /*! + * \brief Gets an entity + * \return A constant reference to a handle of the entity + * + * \param id Identifier of the entity + * + * \remark Handle referenced by this function can move in memory when updating the world, do not keep a reference to a handle from a world update to another + * \remark If an invalid identifier is provided, an error got triggered and an invalid handle is returned + */ + inline const EntityHandle& World::GetEntity(EntityId id) + { + if (IsEntityIdValid(id)) + return m_entityBlocks[id]->handle; + else + { + NazaraError("Invalid ID"); + return EntityHandle::InvalidHandle; + } + } + /*! * \brief Checks whether or not an entity is valid * \return true If it is the case @@ -197,7 +232,7 @@ namespace Ndk inline bool World::IsEntityIdValid(EntityId id) const { - return id < m_entities.size() && m_entities[id].entity.IsValid(); + return id < m_entityBlocks.size() && m_entityBlocks[id]->entity.IsValid(); } /*! @@ -266,10 +301,12 @@ namespace Ndk { m_aliveEntities = std::move(world.m_aliveEntities); m_dirtyEntities = std::move(world.m_dirtyEntities); + m_entityBlocks = std::move(world.m_entityBlocks); m_freeIdList = std::move(world.m_freeIdList); m_killedEntities = std::move(world.m_killedEntities); m_orderedSystems = std::move(world.m_orderedSystems); m_orderedSystemsUpdated = world.m_orderedSystemsUpdated; + m_waitingEntities = std::move(world.m_waitingEntities); m_entities = std::move(world.m_entities); for (EntityBlock& block : m_entities) @@ -284,7 +321,7 @@ namespace Ndk inline void World::Invalidate() { - m_dirtyEntities.Resize(m_entities.size(), false); + m_dirtyEntities.Resize(m_entityBlocks.size(), false); m_dirtyEntities.Set(true); // Activation of all bits } diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 4098b8a2b..c70ec181b 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -164,25 +164,25 @@ namespace Ndk LuaAPI::RegisterClasses(overlay->lua); // Override "print" function to add a line in the console - overlay->lua.PushFunction([&consoleRef] (Nz::LuaInstance& instance) + overlay->lua.PushFunction([&consoleRef] (Nz::LuaState& state) { Nz::StringStream stream; - unsigned int argCount = instance.GetStackTop(); - instance.GetGlobal("tostring"); + unsigned int argCount = state.GetStackTop(); + state.GetGlobal("tostring"); for (unsigned int i = 1; i <= argCount; ++i) { - instance.PushValue(-1); // tostring function - instance.PushValue(i); // argument - instance.Call(1, 1); + state.PushValue(-1); // tostring function + state.PushValue(i); // argument + state.Call(1, 1); std::size_t length; - const char* str = instance.CheckString(-1, &length); + const char* str = state.CheckString(-1, &length); if (i > 1) stream << '\t'; stream << Nz::String(str, length); - instance.Pop(1); + state.Pop(1); } consoleRef.AddLine(stream); diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp index 39d67d211..204076e54 100644 --- a/SDK/src/NDK/BaseComponent.cpp +++ b/SDK/src/NDK/BaseComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -54,6 +54,15 @@ namespace Ndk { } + /*! + * \brief Operation to perform when the entity is destroyed and we're still attached to it + * + * \remark This is always called before the entity proper destruction, and thus its components. + */ + void BaseComponent::OnEntityDestruction() + { + } + std::vector BaseComponent::s_entries; std::unordered_map BaseComponent::s_idToIndex; } diff --git a/SDK/src/NDK/BaseSystem.cpp b/SDK/src/NDK/BaseSystem.cpp index b6ebe9892..c7e6c8741 100644 --- a/SDK/src/NDK/BaseSystem.cpp +++ b/SDK/src/NDK/BaseSystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 43ffbeb52..c4ef2d1f8 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace Ndk { @@ -20,15 +21,22 @@ namespace Ndk m_widgetParent = parent; m_world = m_canvas->GetWorld(); - m_canvasIndex = m_canvas->RegisterWidget(this); + RegisterToCanvas(); } BaseWidget::~BaseWidget() { - m_canvas->UnregisterWidget(m_canvasIndex); + UnregisterFromCanvas(); } - inline void BaseWidget::EnableBackground(bool enable) + void BaseWidget::Destroy() + { + NazaraAssert(this != m_canvas, "Canvas cannot be destroyed by calling Destroy()"); + + m_widgetParent->DestroyChild(this); //< This does delete us + } + + void BaseWidget::EnableBackground(bool enable) { if (m_backgroundEntity.IsValid() == enable) return; @@ -39,7 +47,7 @@ namespace Ndk m_backgroundSprite->SetColor(m_backgroundColor); m_backgroundSprite->SetMaterial(Nz::Material::New((m_backgroundColor.IsOpaque()) ? "Basic2D" : "Translucent2D")); - m_backgroundEntity = m_world->CreateEntity(); + m_backgroundEntity = CreateEntity(); m_backgroundEntity->AddComponent().Attach(m_backgroundSprite, -1); m_backgroundEntity->AddComponent().SetParent(this); @@ -52,15 +60,61 @@ namespace Ndk } } + void BaseWidget::GrabKeyboard() + { + m_canvas->SetKeyboardOwner(this); + } + + void BaseWidget::SetBackgroundColor(const Nz::Color& color) + { + m_backgroundColor = color; + + if (m_backgroundSprite) + { + m_backgroundSprite->SetColor(color); + m_backgroundSprite->GetMaterial()->Configure((color.IsOpaque()) ? "Basic2D" : "Translucent2D"); //< Our sprite has its own material (see EnableBackground) + } + } + + void BaseWidget::SetCursor(Nz::SystemCursor systemCursor) + { + m_cursor = systemCursor; + + if (IsRegisteredToCanvas()) + m_canvas->NotifyWidgetCursorUpdate(m_canvasIndex); + } + void BaseWidget::SetSize(const Nz::Vector2f& size) { SetContentSize({std::max(size.x - m_padding.left - m_padding.right, 0.f), std::max(size.y - m_padding.top - m_padding.bottom, 0.f)}); } + void BaseWidget::Show(bool show) + { + if (m_visible != show) + { + m_visible = show; + + if (m_visible) + RegisterToCanvas(); + else + UnregisterFromCanvas(); + + for (const EntityHandle& entity : m_entities) + entity->Enable(show); + + for (const auto& widgetPtr : m_children) + widgetPtr->Show(show); + } + } + EntityHandle BaseWidget::CreateEntity() { - m_entities.emplace_back(m_world->CreateEntity()); - return m_entities.back(); + EntityHandle newEntity = m_world->CreateEntity(); + newEntity->Enable(m_visible); + + m_entities.emplace_back(newEntity); + return newEntity; } void BaseWidget::DestroyEntity(Entity* entity) @@ -71,31 +125,21 @@ namespace Ndk m_entities.erase(it); } - void BaseWidget::GrabKeyboard() - { - m_canvas->SetKeyboardOwner(this); - } - void BaseWidget::Layout() { - if (m_canvas) - m_canvas->NotifyWidgetUpdate(m_canvasIndex); + if (IsRegisteredToCanvas()) + m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex); if (m_backgroundEntity) - { - NodeComponent& node = m_backgroundEntity->GetComponent(); - node.SetPosition(-m_padding.left, -m_padding.top); - m_backgroundSprite->SetSize(m_contentSize.x + m_padding.left + m_padding.right, m_contentSize.y + m_padding.top + m_padding.bottom); - } } void BaseWidget::InvalidateNode() { Node::InvalidateNode(); - if (m_canvas) - m_canvas->NotifyWidgetUpdate(m_canvasIndex); + if (IsRegisteredToCanvas()) + m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex); } void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) @@ -126,7 +170,44 @@ namespace Ndk { } + void BaseWidget::OnParentResized(const Nz::Vector2f& newSize) + { + } + void BaseWidget::OnTextEntered(char32_t character, bool repeated) { } + + void BaseWidget::DestroyChild(BaseWidget* widget) + { + auto it = std::find_if(m_children.begin(), m_children.end(), [widget] (const std::unique_ptr& widgetPtr) -> bool + { + return widgetPtr.get() == widget; + }); + + NazaraAssert(it != m_children.end(), "Child widget not found in parent"); + + m_children.erase(it); + } + + void BaseWidget::DestroyChildren() + { + m_children.clear(); + } + + void BaseWidget::RegisterToCanvas() + { + NazaraAssert(!IsRegisteredToCanvas(), "Widget is already registered to canvas"); + + m_canvasIndex = m_canvas->RegisterWidget(this); + } + + void BaseWidget::UnregisterFromCanvas() + { + if (IsRegisteredToCanvas()) + { + m_canvas->UnregisterWidget(m_canvasIndex); + m_canvasIndex = InvalidCanvasIndex; + } + } } diff --git a/SDK/src/NDK/Canvas.cpp b/SDK/src/NDK/Canvas.cpp index c06d320c1..84e4b5bd8 100644 --- a/SDK/src/NDK/Canvas.cpp +++ b/SDK/src/NDK/Canvas.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -14,56 +14,38 @@ namespace Ndk { } - void Canvas::Layout() - { - if (m_backgroundEntity) - { - NodeComponent& node = m_backgroundEntity->GetComponent(); - node.SetPosition(-m_padding.left, -m_padding.top); - - m_backgroundSprite->SetSize(m_contentSize.x + m_padding.left + m_padding.right, m_contentSize.y + m_padding.top + m_padding.bottom); - } - } - - void Canvas::NotifyWidgetUpdate(std::size_t index) - { - WidgetBox& entry = m_widgetBoxes[index]; - - Nz::Vector3f pos = entry.widget->GetPosition(); - Nz::Vector2f size = entry.widget->GetContentSize(); - - entry.box.Set(pos.x, pos.y, pos.z, size.x, size.y, 1.f); - } - std::size_t Canvas::RegisterWidget(BaseWidget* widget) { WidgetBox box; + box.cursor = widget->GetCursor(); box.widget = widget; std::size_t index = m_widgetBoxes.size(); m_widgetBoxes.emplace_back(box); - NotifyWidgetUpdate(index); + NotifyWidgetBoxUpdate(index); return index; } void Canvas::UnregisterWidget(std::size_t index) { + WidgetBox& entry = m_widgetBoxes[index]; + + if (m_hoveredWidget == &entry) + m_hoveredWidget = nullptr; + + if (m_keyboardOwner == entry.widget) + m_keyboardOwner = nullptr; + if (m_widgetBoxes.size() > 1U) { - WidgetBox& entry = m_widgetBoxes[index]; WidgetBox& lastEntry = m_widgetBoxes.back(); - if (m_hoveredWidget == &entry) - m_hoveredWidget = nullptr; - - if (m_keyboardOwner == entry.widget) - m_keyboardOwner = nullptr; - entry = std::move(lastEntry); entry.widget->UpdateCanvasIndex(index); - m_widgetBoxes.pop_back(); } + + m_widgetBoxes.pop_back(); } void Canvas::OnMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event) @@ -93,11 +75,12 @@ namespace Ndk const WidgetBox* bestEntry = nullptr; float bestEntryArea = std::numeric_limits::infinity(); + Nz::Vector3f mousePos(float(event.x), float(event.y), 0.f); for (const WidgetBox& entry : m_widgetBoxes) { const Nz::Boxf& box = entry.box; - if (box.Contains(Nz::Vector3f(event.x, event.y, 0.f))) + if (box.Contains(mousePos)) { float area = box.width * box.height; if (area < bestEntryArea) @@ -117,6 +100,9 @@ namespace Ndk m_hoveredWidget = bestEntry; m_hoveredWidget->widget->OnMouseEnter(); + + if (m_cursorController) + m_cursorController->UpdateCursor(Nz::Cursor::Get(m_hoveredWidget->cursor)); } int x = static_cast(std::round(event.x - m_hoveredWidget->box.x)); @@ -128,6 +114,9 @@ namespace Ndk { m_hoveredWidget->widget->OnMouseExit(); m_hoveredWidget = nullptr; + + if (m_cursorController) + m_cursorController->UpdateCursor(Nz::Cursor::Get(Nz::SystemCursor_Default)); } } diff --git a/SDK/src/NDK/Components/CameraComponent.cpp b/SDK/src/NDK/Components/CameraComponent.cpp index ae1c129c3..2441dd7a8 100644 --- a/SDK/src/NDK/Components/CameraComponent.cpp +++ b/SDK/src/NDK/Components/CameraComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -93,6 +93,17 @@ namespace Ndk return m_projectionMatrix; } + + /*! + * \brief Gets the projection type of the camera + * \return Projection type of the camera + */ + Nz::ProjectionType CameraComponent::GetProjectionType() const + { + return m_projectionType; + } + + /*! * \brief Gets the target of the camera * \return A constant reference to the render target of the camera diff --git a/SDK/src/NDK/Components/CollisionComponent2D.cpp b/SDK/src/NDK/Components/CollisionComponent2D.cpp index 912742b0e..ff10019f6 100644 --- a/SDK/src/NDK/Components/CollisionComponent2D.cpp +++ b/SDK/src/NDK/Components/CollisionComponent2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/CollisionComponent3D.cpp b/SDK/src/NDK/Components/CollisionComponent3D.cpp index d54c460be..4ec2bff81 100644 --- a/SDK/src/NDK/Components/CollisionComponent3D.cpp +++ b/SDK/src/NDK/Components/CollisionComponent3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 8a8516e16..8ec5319cd 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/LightComponent.cpp b/SDK/src/NDK/Components/LightComponent.cpp index d49d5f8f9..f463eb52d 100644 --- a/SDK/src/NDK/Components/LightComponent.cpp +++ b/SDK/src/NDK/Components/LightComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/ListenerComponent.cpp b/SDK/src/NDK/Components/ListenerComponent.cpp index 7d88c5be5..3d261fcb3 100644 --- a/SDK/src/NDK/Components/ListenerComponent.cpp +++ b/SDK/src/NDK/Components/ListenerComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/NodeComponent.cpp b/SDK/src/NDK/Components/NodeComponent.cpp index 40584236a..d54da5ecb 100644 --- a/SDK/src/NDK/Components/NodeComponent.cpp +++ b/SDK/src/NDK/Components/NodeComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/ParticleEmitterComponent.cpp b/SDK/src/NDK/Components/ParticleEmitterComponent.cpp index e700b6497..89cbaf983 100644 --- a/SDK/src/NDK/Components/ParticleEmitterComponent.cpp +++ b/SDK/src/NDK/Components/ParticleEmitterComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/ParticleGroupComponent.cpp b/SDK/src/NDK/Components/ParticleGroupComponent.cpp index 4e0845871..c9c64f1e4 100644 --- a/SDK/src/NDK/Components/ParticleGroupComponent.cpp +++ b/SDK/src/NDK/Components/ParticleGroupComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Components/PhysicsComponent2D.cpp b/SDK/src/NDK/Components/PhysicsComponent2D.cpp index db66178b9..58cab2982 100644 --- a/SDK/src/NDK/Components/PhysicsComponent2D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -88,5 +88,11 @@ namespace Ndk m_object.reset(); } + void PhysicsComponent2D::OnEntityDestruction() + { + // Kill rigidbody before entity destruction to force contact callbacks to be called while the entity is still valid + m_object.reset(); + } + ComponentIndex PhysicsComponent2D::componentIndex; } diff --git a/SDK/src/NDK/Components/PhysicsComponent3D.cpp b/SDK/src/NDK/Components/PhysicsComponent3D.cpp index 7dfffab85..31b3fb6ac 100644 --- a/SDK/src/NDK/Components/PhysicsComponent3D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -88,5 +88,11 @@ namespace Ndk m_object.reset(); } + void PhysicsComponent3D::OnEntityDestruction() + { + // Kill rigid body before entity destruction to force contact callbacks to be called while the entity is still valid + m_object.reset(); + } + ComponentIndex PhysicsComponent3D::componentIndex; } diff --git a/SDK/src/NDK/Components/VelocityComponent.cpp b/SDK/src/NDK/Components/VelocityComponent.cpp index 15c5ca31f..be1fcec02 100644 --- a/SDK/src/NDK/Components/VelocityComponent.cpp +++ b/SDK/src/NDK/Components/VelocityComponent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 82d3d40af..a59bfdf81 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -33,10 +33,10 @@ namespace Ndk * \param instance Lua instance that will interact with the world */ - Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) : + Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaState& state) : m_historyPosition(0), m_defaultFont(Nz::Font::GetDefault()), - m_instance(instance), + m_state(state), m_size(size), m_opened(false), m_characterSize(24) @@ -192,9 +192,12 @@ namespace Ndk m_historyPosition = 1; } - Nz::String text = m_commandHistory[m_commandHistory.size() - m_historyPosition]; - m_inputDrawer.SetText(s_inputPrefix + text); - m_inputTextSprite->Update(m_inputDrawer); + if (!m_commandHistory.empty()) + { + Nz::String text = m_commandHistory[m_commandHistory.size() - m_historyPosition]; + m_inputDrawer.SetText(s_inputPrefix + text); + m_inputTextSprite->Update(m_inputDrawer); + } break; } @@ -297,7 +300,7 @@ namespace Ndk void Console::ExecuteInput() { Nz::String input = m_inputDrawer.GetText(); - Nz::String inputCmd = input.SubString(s_inputPrefixSize);; + Nz::String inputCmd = input.SubString(s_inputPrefixSize); m_inputDrawer.SetText(s_inputPrefix); if (m_commandHistory.empty() || m_commandHistory.back() != inputCmd) @@ -307,8 +310,8 @@ namespace Ndk AddLineInternal(input); //< With the input prefix - if (!m_instance.Execute(inputCmd)) - AddLineInternal(m_instance.GetLastError(), Nz::Color::Red); + if (!m_state.Execute(inputCmd)) + AddLineInternal(m_state.GetLastError(), Nz::Color::Red); RefreshHistory(); } diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 4f60bb427..fab08b237 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -23,13 +23,16 @@ namespace Ndk Entity::Entity(Entity&& entity) : HandledObject(std::move(entity)), m_components(std::move(entity.m_components)), + m_containedInLists(std::move(entity.m_containedInLists)), m_componentBits(std::move(entity.m_componentBits)), + m_removedComponentBits(std::move(entity.m_removedComponentBits)), m_systemBits(std::move(entity.m_systemBits)), m_id(entity.m_id), m_world(entity.m_world), m_enabled(entity.m_enabled), m_valid(entity.m_valid) { + entity.m_world = nullptr; } /*! @@ -53,7 +56,8 @@ namespace Ndk Entity::~Entity() { - Destroy(); + if (m_world) + Destroy(); } /*! @@ -145,6 +149,17 @@ namespace Ndk void Entity::Destroy() { + OnEntityDestruction(this); + OnEntityDestruction.Clear(); + + // We prepare components for entity destruction (some components needs this to handle some final callbacks while the entity is still valid) + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + m_components[i]->OnEntityDestruction(); + + // Detach components while they're still attached to systems + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + m_components[i]->SetEntity(nullptr); + // We alert each system for (std::size_t index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) { @@ -158,11 +173,19 @@ namespace Ndk } m_systemBits.Clear(); - UnregisterAllHandles(); - + // Destroy components m_components.clear(); m_componentBits.Reset(); + // Free every handle + UnregisterAllHandles(); + + // Remove from every list + for (EntityList* list : m_containedInLists) + list->NotifyEntityDestruction(this); + + m_containedInLists.clear(); + m_valid = false; } diff --git a/SDK/src/NDK/EntityList.cpp b/SDK/src/NDK/EntityList.cpp new file mode 100644 index 000000000..03fd3afc3 --- /dev/null +++ b/SDK/src/NDK/EntityList.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include + +namespace Ndk +{ + const EntityHandle& EntityList::iterator::operator*() const + { + return m_list->GetWorld()->GetEntity(static_cast(m_nextEntityId)); + } +} diff --git a/SDK/src/NDK/Lua/LuaBinding.cpp b/SDK/src/NDK/Lua/LuaBinding.cpp index cb763b3b4..715351e52 100644 --- a/SDK/src/NDK/Lua/LuaBinding.cpp +++ b/SDK/src/NDK/Lua/LuaBinding.cpp @@ -22,7 +22,7 @@ namespace Ndk utility = LuaBinding_Base::BindUtility(*this); #ifndef NDK_SERVER - audio = LuaBinding_Base::BindAudio(*this); + audio = LuaBinding_Base::BindAudio(*this); renderer = LuaBinding_Base::BindRenderer(*this); graphics = LuaBinding_Base::BindGraphics(*this); #endif @@ -36,31 +36,31 @@ namespace Ndk * \param instance Lua instance that will interact with the engine & SDK */ - void LuaBinding::RegisterClasses(Nz::LuaInstance& instance) + void LuaBinding::RegisterClasses(Nz::LuaState& state) { - core->Register(instance); - math->Register(instance); - network->Register(instance); - sdk->Register(instance); - utility->Register(instance); + core->Register(state); + math->Register(state); + network->Register(state); + sdk->Register(state); + utility->Register(state); #ifndef NDK_SERVER - audio->Register(instance); - graphics->Register(instance); - renderer->Register(instance); + audio->Register(state); + graphics->Register(state); + renderer->Register(state); #endif // ComponentType (fake enumeration to expose component indexes) - instance.PushTable(0, m_componentBinding.size()); + state.PushTable(0, m_componentBinding.size()); { for (const ComponentBinding& entry : m_componentBinding) { if (entry.name.IsEmpty()) continue; - instance.PushField(entry.name, entry.index); + state.PushField(entry.name, entry.index); } } - instance.SetGlobal("ComponentType"); + state.SetGlobal("ComponentType"); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Audio.cpp b/SDK/src/NDK/Lua/LuaBinding_Audio.cpp index 619fe2850..1611c1b8c 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Audio.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Audio.cpp @@ -77,7 +77,7 @@ namespace Ndk music.BindMethod("Stop", &Nz::Music::Stop); // Manual - music.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Music& instance, std::size_t /*argumentCount*/) -> int + music.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Music& instance, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("Music("); ss << instance.GetFilePath() << ')'; @@ -104,7 +104,7 @@ namespace Ndk sound.BindMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset); // Manual - sound.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& instance, std::size_t /*argumentCount*/) -> int + sound.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Sound& instance, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("Sound("); if (const Nz::SoundBuffer* buffer = instance.GetBuffer()) @@ -120,7 +120,7 @@ namespace Ndk /*********************************** Nz::SoundBuffer **********************************/ soundBuffer.Reset("SoundBuffer"); { - soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance, std::size_t argumentCount) + soundBuffer.SetConstructor([] (Nz::LuaState& lua, Nz::SoundBufferRef* instance, std::size_t argumentCount) { NazaraUnused(lua); NazaraUnused(argumentCount); @@ -143,7 +143,7 @@ namespace Ndk soundBuffer.BindStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported); // Manual - soundBuffer.BindMethod("Create", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int + soundBuffer.BindMethod("Create", [] (Nz::LuaState& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int { int index = 2; Nz::AudioFormat format = lua.Check(&index); @@ -158,13 +158,13 @@ namespace Ndk return 1; }); - soundBuffer.BindMethod("GetSamples", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int + soundBuffer.BindMethod("GetSamples", [] (Nz::LuaState& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int { lua.PushString(reinterpret_cast(instance->GetSamples()), instance->GetSampleCount() * sizeof(Nz::Int16)); return 1; }); - soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int + soundBuffer.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("SoundBuffer("); if (instance->IsValid()) @@ -188,11 +188,11 @@ namespace Ndk * * \param instance Lua instance that will interact with the Audio classes */ - void LuaBinding_Audio::Register(Nz::LuaInstance& instance) + void LuaBinding_Audio::Register(Nz::LuaState& state) { - music.Register(instance); - sound.Register(instance); - soundBuffer.Register(instance); - soundEmitter.Register(instance); + music.Register(state); + sound.Register(state); + soundBuffer.Register(state); + soundEmitter.Register(state); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Core.cpp b/SDK/src/NDK/Lua/LuaBinding_Core.cpp index fc53f72c3..f86aafa98 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Core.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Core.cpp @@ -32,28 +32,28 @@ namespace Ndk stream.BindMethod("IsWritable", &Nz::Stream::IsWritable); stream.BindMethod("SetCursorPos", &Nz::Stream::SetCursorPos); - stream.BindMethod("Read", [] (Nz::LuaInstance& lua, Nz::Stream& instance, std::size_t /*argumentCount*/) -> int { + stream.BindMethod("Read", [] (Nz::LuaState& lua, Nz::Stream& stream, std::size_t /*argumentCount*/) -> int { int argIndex = 2; std::size_t length = lua.Check(&argIndex); std::unique_ptr buffer(new char[length]); - std::size_t readLength = instance.Read(buffer.get(), length); + std::size_t readLength = stream.Read(buffer.get(), length); lua.PushString(Nz::String(buffer.get(), readLength)); return 1; }); - stream.BindMethod("Write", [] (Nz::LuaInstance& lua, Nz::Stream& instance, std::size_t /*argumentCount*/) -> int { + stream.BindMethod("Write", [] (Nz::LuaState& lua, Nz::Stream& stream, std::size_t /*argumentCount*/) -> int { int argIndex = 2; std::size_t bufferSize = 0; const char* buffer = lua.CheckString(argIndex, &bufferSize); - if (instance.IsTextModeEnabled()) - lua.Push(instance.Write(Nz::String(buffer, bufferSize))); + if (stream.IsTextModeEnabled()) + lua.Push(stream.Write(Nz::String(buffer, bufferSize))); else - lua.Push(instance.Write(buffer, bufferSize)); + lua.Push(stream.Write(buffer, bufferSize)); return 1; }); } @@ -61,7 +61,7 @@ namespace Ndk /*********************************** Nz::Clock **********************************/ clock.Reset("Clock"); { - clock.SetConstructor([] (Nz::LuaInstance& lua, Nz::Clock* instance, std::size_t argumentCount) + clock.SetConstructor([] (Nz::LuaState& lua, Nz::Clock* instance, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 2U); @@ -103,11 +103,11 @@ namespace Ndk clock.BindMethod("Unpause", &Nz::Clock::Unpause); // Manual - clock.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& instance, std::size_t /*argumentCount*/) -> int { + clock.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Clock& clock, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("Clock(Elapsed: "); - ss << instance.GetSeconds(); + ss << clock.GetSeconds(); ss << "s, Paused: "; - ss << instance.IsPaused(); + ss << clock.IsPaused(); ss << ')'; lua.PushString(ss); @@ -118,7 +118,7 @@ namespace Ndk /********************************* Nz::Directory ********************************/ directory.Reset("Directory"); { - directory.SetConstructor([] (Nz::LuaInstance& lua, Nz::Directory* instance, std::size_t argumentCount) + directory.SetConstructor([] (Nz::LuaState& lua, Nz::Directory* instance, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 1U); @@ -159,9 +159,9 @@ namespace Ndk directory.BindStaticMethod("SetCurrent", Nz::Directory::SetCurrent); // Manual - directory.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Directory& instance, std::size_t /*argumentCount*/) -> int { + directory.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Directory& dir, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("Directory("); - ss << instance.GetPath(); + ss << dir.GetPath(); ss << ')'; lua.PushString(ss); @@ -174,7 +174,7 @@ namespace Ndk { file.Inherit(stream); - file.SetConstructor([] (Nz::LuaInstance& lua, Nz::File* instance, std::size_t argumentCount) + file.SetConstructor([] (Nz::LuaState& lua, Nz::File* instance, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 1U); @@ -237,7 +237,7 @@ namespace Ndk file.BindStaticMethod("Rename", &Nz::File::Rename); // Manual - file.BindMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& instance, std::size_t argumentCount) -> int + file.BindMethod("Open", [] (Nz::LuaState& lua, Nz::File& file, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 2U); @@ -246,13 +246,13 @@ namespace Ndk { case 0: case 1: - return lua.Push(instance.Open(lua.Check(&argIndex, Nz::OpenMode_NotOpen))); + return lua.Push(file.Open(lua.Check(&argIndex, Nz::OpenMode_NotOpen))); case 2: { Nz::String filePath = lua.Check(&argIndex); Nz::UInt32 openMode = lua.Check(&argIndex, Nz::OpenMode_NotOpen); - return lua.Push(instance.Open(filePath, openMode)); + return lua.Push(file.Open(filePath, openMode)); } } @@ -260,7 +260,7 @@ namespace Ndk return 0; }); - file.BindMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& instance, std::size_t argumentCount) -> int + file.BindMethod("SetCursorPos", [] (Nz::LuaState& lua, Nz::File& file, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 2U); @@ -268,13 +268,13 @@ namespace Ndk switch (argCount) { case 1: - return lua.Push(instance.SetCursorPos(lua.Check(&argIndex))); + return lua.Push(file.SetCursorPos(lua.Check(&argIndex))); case 2: { Nz::CursorPosition curPos = lua.Check(&argIndex); Nz::Int64 offset = lua.Check(&argIndex); - return lua.Push(instance.SetCursorPos(curPos, offset)); + return lua.Push(file.SetCursorPos(curPos, offset)); } } @@ -282,10 +282,10 @@ namespace Ndk return 0; }); - file.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::File& instance, std::size_t /*argumentCount*/) -> int { + file.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::File& file, std::size_t /*argumentCount*/) -> int { Nz::StringStream ss("File("); - if (instance.IsOpen()) - ss << "Path: " << instance.GetPath(); + if (file.IsOpen()) + ss << "Path: " << file.GetPath(); ss << ')'; @@ -300,55 +300,55 @@ namespace Ndk * * \param instance Lua instance that will interact with the Core classes */ - void LuaBinding_Core::Register(Nz::LuaInstance& instance) + void LuaBinding_Core::Register(Nz::LuaState& state) { // Classes - clock.Register(instance); - directory.Register(instance); - file.Register(instance); - stream.Register(instance); + clock.Register(state); + directory.Register(state); + file.Register(state); + stream.Register(state); // Enums // 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); + state.PushTable(0, 3); { - instance.PushField("AtBegin", Nz::CursorPosition_AtBegin); - instance.PushField("AtCurrent", Nz::CursorPosition_AtCurrent); - instance.PushField("AtEnd", Nz::CursorPosition_AtEnd); + state.PushField("AtBegin", Nz::CursorPosition_AtBegin); + state.PushField("AtCurrent", Nz::CursorPosition_AtCurrent); + state.PushField("AtEnd", Nz::CursorPosition_AtEnd); } - instance.SetGlobal("CursorPosition"); + state.SetGlobal("CursorPosition"); // 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); + state.PushTable(0, 9); { - instance.PushField("CRC32", Nz::HashType_CRC32); - instance.PushField("Fletcher16", Nz::HashType_Fletcher16); - instance.PushField("MD5", Nz::HashType_MD5); - instance.PushField("SHA1", Nz::HashType_SHA1); - instance.PushField("SHA224", Nz::HashType_SHA224); - instance.PushField("SHA256", Nz::HashType_SHA256); - instance.PushField("SHA384", Nz::HashType_SHA384); - instance.PushField("SHA512", Nz::HashType_SHA512); - instance.PushField("Whirlpool", Nz::HashType_Whirlpool); + state.PushField("CRC32", Nz::HashType_CRC32); + state.PushField("Fletcher16", Nz::HashType_Fletcher16); + state.PushField("MD5", Nz::HashType_MD5); + state.PushField("SHA1", Nz::HashType_SHA1); + state.PushField("SHA224", Nz::HashType_SHA224); + state.PushField("SHA256", Nz::HashType_SHA256); + state.PushField("SHA384", Nz::HashType_SHA384); + state.PushField("SHA512", Nz::HashType_SHA512); + state.PushField("Whirlpool", Nz::HashType_Whirlpool); } - instance.SetGlobal("HashType"); + state.SetGlobal("HashType"); // Nz::OpenMode static_assert(Nz::OpenMode_Max + 1 == 8, "Nz::OpenModeFlags has been updated but change was not reflected to Lua binding"); - instance.PushTable(0, Nz::OpenMode_Max + 1); + state.PushTable(0, Nz::OpenMode_Max + 1); { - instance.PushField("Append", Nz::OpenMode_Append); - instance.PushField("NotOpen", Nz::OpenMode_NotOpen); - instance.PushField("Lock", Nz::OpenMode_Lock); - instance.PushField("ReadOnly", Nz::OpenMode_ReadOnly); - instance.PushField("ReadWrite", Nz::OpenMode_ReadWrite); - instance.PushField("Text", Nz::OpenMode_Text); - instance.PushField("Truncate", Nz::OpenMode_Truncate); - instance.PushField("WriteOnly", Nz::OpenMode_WriteOnly); + state.PushField("Append", Nz::OpenMode_Append); + state.PushField("NotOpen", Nz::OpenMode_NotOpen); + state.PushField("Lock", Nz::OpenMode_Lock); + state.PushField("ReadOnly", Nz::OpenMode_ReadOnly); + state.PushField("ReadWrite", Nz::OpenMode_ReadWrite); + state.PushField("Text", Nz::OpenMode_Text); + state.PushField("Truncate", Nz::OpenMode_Truncate); + state.PushField("WriteOnly", Nz::OpenMode_WriteOnly); } - instance.SetGlobal("OpenMode"); + state.SetGlobal("OpenMode"); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp index f87ac6556..d33811f49 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp @@ -37,7 +37,7 @@ namespace Ndk /*********************************** Nz::Material ***********************************/ material.Reset("Material"); { - material.SetConstructor([] (Nz::LuaInstance& lua, Nz::MaterialRef* instance, std::size_t argumentCount) + material.SetConstructor([] (Nz::LuaState& lua, Nz::MaterialRef* instance, std::size_t argumentCount) { switch (argumentCount) { @@ -70,7 +70,7 @@ namespace Ndk return false; }); - material.BindMethod("Configure", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("Configure", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "MaterialPipeline")) @@ -168,7 +168,7 @@ namespace Ndk material.BindStaticMethod("GetDefault", &Nz::Material::GetDefault); - material.BindMethod("SetAlphaMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetAlphaMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Texture")) @@ -180,7 +180,7 @@ namespace Ndk return lua.Push(instance->SetAlphaMap(lua.Check(&argIndex))); }); - material.BindMethod("SetDiffuseMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetDiffuseMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Texture")) @@ -192,7 +192,7 @@ namespace Ndk return lua.Push(instance->SetDiffuseMap(lua.Check(&argIndex))); }); - material.BindMethod("SetEmissiveMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetEmissiveMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Texture")) @@ -204,7 +204,7 @@ namespace Ndk return lua.Push(instance->SetEmissiveMap(lua.Check(&argIndex))); }); - material.BindMethod("SetHeightMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetHeightMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Texture")) @@ -216,7 +216,7 @@ namespace Ndk return lua.Push(instance->SetHeightMap(lua.Check(&argIndex))); }); - material.BindMethod("SetNormalMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetNormalMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Texture")) @@ -228,7 +228,7 @@ namespace Ndk return lua.Push(instance->SetNormalMap(lua.Check(&argIndex))); }); - material.BindMethod("SetShader", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetShader", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "UberShader")) @@ -240,7 +240,7 @@ namespace Ndk return lua.Push(instance->SetShader(lua.Check(&argIndex))); }); - material.BindMethod("SetSpecularMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int + material.BindMethod("SetSpecularMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Texture")) @@ -261,7 +261,7 @@ namespace Ndk return reinterpret_cast(modelRef); //TODO: Make a ObjectRefCast }); - model.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::ModelRef* instance, std::size_t /*argumentCount*/) + model.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::ModelRef* instance, std::size_t /*argumentCount*/) { Nz::PlacementNew(instance, Nz::Model::New()); return true; @@ -293,7 +293,7 @@ namespace Ndk return reinterpret_cast(spriteRef); //TODO: Make a ObjectRefCast }); - sprite.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::SpriteRef* instance, std::size_t /*argumentCount*/) + sprite.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::SpriteRef* instance, std::size_t /*argumentCount*/) { Nz::PlacementNew(instance, Nz::Sprite::New()); return true; @@ -314,7 +314,7 @@ namespace Ndk sprite.BindMethod("SetTextureCoords", &Nz::Sprite::SetTextureCoords); sprite.BindMethod("SetTextureRect", &Nz::Sprite::SetTextureRect); - sprite.BindMethod("SetMaterial", [] (Nz::LuaInstance& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int + sprite.BindMethod("SetMaterial", [] (Nz::LuaState& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); @@ -327,7 +327,7 @@ namespace Ndk return 0; }); - sprite.BindMethod("SetTexture", [] (Nz::LuaInstance& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int + sprite.BindMethod("SetTexture", [] (Nz::LuaState& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; bool resizeSprite = lua.CheckBoolean(argIndex + 1, true); @@ -358,13 +358,13 @@ namespace Ndk * \param instance Lua instance that will interact with the Graphics classes */ - void LuaBinding_Graphics::Register(Nz::LuaInstance& instance) + void LuaBinding_Graphics::Register(Nz::LuaState& state) { - abstractViewer.Register(instance); - instancedRenderable.Register(instance); - material.Register(instance); - model.Register(instance); - sprite.Register(instance); - spriteLibrary.Register(instance); + abstractViewer.Register(state); + instancedRenderable.Register(state); + material.Register(state); + model.Register(state); + sprite.Register(state); + spriteLibrary.Register(state); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Math.cpp b/SDK/src/NDK/Lua/LuaBinding_Math.cpp index 6d30bb137..c218c2a66 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Math.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Math.cpp @@ -18,9 +18,9 @@ namespace Ndk /*********************************** Nz::EulerAngles **********************************/ eulerAngles.Reset("EulerAngles"); { - eulerAngles.SetConstructor([] (Nz::LuaInstance& lua, Nz::EulerAnglesd* instance, std::size_t argumentCount) + eulerAngles.SetConstructor([] (Nz::LuaState& lua, Nz::EulerAnglesd* instance, std::size_t argumentCount) { - std::size_t argCount = std::min(argumentCount, 1U); + std::size_t argCount = std::min(argumentCount, 3U); switch (argCount) { @@ -46,7 +46,7 @@ namespace Ndk eulerAngles.BindMethod("__tostring", &Nz::EulerAnglesd::ToString); - eulerAngles.SetGetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) + eulerAngles.SetGetter([] (Nz::LuaState& lua, Nz::EulerAnglesd& instance) { std::size_t length; const char* ypr = lua.CheckString(2, &length); @@ -103,7 +103,7 @@ namespace Ndk return false; }); - eulerAngles.SetSetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) + eulerAngles.SetSetter([] (Nz::LuaState& lua, Nz::EulerAnglesd& instance) { std::size_t length; const char* ypr = lua.CheckString(2, &length); @@ -165,7 +165,7 @@ namespace Ndk /*********************************** Nz::Matrix4 **********************************/ matrix4d.Reset("Matrix4"); { - matrix4d.SetConstructor([] (Nz::LuaInstance& lua, Nz::Matrix4d* matrix, std::size_t argumentCount) + matrix4d.SetConstructor([] (Nz::LuaState& lua, Nz::Matrix4d* matrix, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 3U); @@ -207,7 +207,7 @@ namespace Ndk matrix4d.BindMethod("GetDeterminant", &Nz::Matrix4d::GetDeterminant); matrix4d.BindMethod("GetDeterminantAffine", &Nz::Matrix4d::GetDeterminantAffine); - matrix4d.BindMethod("GetInverse", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int + matrix4d.BindMethod("GetInverse", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int { Nz::Matrix4d result; if (instance.GetInverse(&result)) @@ -216,7 +216,7 @@ namespace Ndk return lua.Push(false); }); - matrix4d.BindMethod("GetInverseAffine", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int + matrix4d.BindMethod("GetInverseAffine", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int { Nz::Matrix4d result; if (instance.GetInverseAffine(&result)) @@ -232,7 +232,7 @@ namespace Ndk matrix4d.BindMethod("GetSquaredScale", &Nz::Matrix4d::GetSquaredScale); matrix4d.BindMethod("GetTranslation", &Nz::Matrix4d::GetTranslation); - matrix4d.BindMethod("GetTransposed", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int + matrix4d.BindMethod("GetTransposed", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int { Nz::Matrix4d result; instance.GetTransposed(&result); @@ -243,7 +243,7 @@ namespace Ndk matrix4d.BindMethod("HasNegativeScale", &Nz::Matrix4d::HasNegativeScale); matrix4d.BindMethod("HasScale", &Nz::Matrix4d::HasScale); - matrix4d.BindMethod("Inverse", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int + matrix4d.BindMethod("Inverse", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int { bool succeeded; instance.Inverse(&succeeded); @@ -251,7 +251,7 @@ namespace Ndk return lua.Push(succeeded); }); - matrix4d.BindMethod("InverseAffine", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int + matrix4d.BindMethod("InverseAffine", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int { bool succeeded; instance.InverseAffine(&succeeded); @@ -273,7 +273,7 @@ namespace Ndk matrix4d.BindMethod("MakeViewMatrix", &Nz::Matrix4d::MakeViewMatrix); matrix4d.BindMethod("MakeZero", &Nz::Matrix4d::MakeZero); - matrix4d.BindMethod("Set", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t argumentCount) -> int + matrix4d.BindMethod("Set", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 3U); @@ -305,7 +305,7 @@ namespace Ndk matrix4d.BindMethod("SetScale", &Nz::Matrix4d::SetScale); matrix4d.BindMethod("SetTranslation", &Nz::Matrix4d::SetTranslation); - matrix4d.BindMethod("Transform", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int + matrix4d.BindMethod("Transform", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int { int argIndex = 2; if (lua.IsOfType(argIndex, "Vector2")) @@ -345,7 +345,7 @@ namespace Ndk matrix4d.BindStaticMethod("ViewMatrix", &Nz::Matrix4d::ViewMatrix); matrix4d.BindStaticMethod("Zero", &Nz::Matrix4d::Zero); - matrix4d.SetGetter([] (Nz::LuaInstance& lua, Nz::Matrix4d& instance) + matrix4d.SetGetter([] (Nz::LuaState& lua, Nz::Matrix4d& instance) { bool succeeded = false; std::size_t index = static_cast(lua.ToInteger(2, &succeeded)); @@ -356,7 +356,7 @@ namespace Ndk return true; }); - matrix4d.SetSetter([] (Nz::LuaInstance& lua, Nz::Matrix4d& instance) + matrix4d.SetSetter([] (Nz::LuaState& lua, Nz::Matrix4d& instance) { bool succeeded = false; std::size_t index = static_cast(lua.ToInteger(2, &succeeded)); @@ -372,7 +372,7 @@ namespace Ndk /*********************************** Nz::Rect **********************************/ rect.Reset("Rect"); { - rect.SetConstructor([] (Nz::LuaInstance& lua, Nz::Rectd* instance, std::size_t argumentCount) + rect.SetConstructor([] (Nz::LuaState& lua, Nz::Rectd* instance, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 4U); @@ -422,7 +422,7 @@ namespace Ndk rect.BindMethod("__tostring", &Nz::Rectd::ToString); - rect.SetGetter([] (Nz::LuaInstance& lua, Nz::Rectd& instance) + rect.SetGetter([] (Nz::LuaState& lua, Nz::Rectd& instance) { switch (lua.GetType(2)) { @@ -475,7 +475,7 @@ namespace Ndk return false; }); - rect.SetSetter([] (Nz::LuaInstance& lua, Nz::Rectd& instance) + rect.SetSetter([] (Nz::LuaState& lua, Nz::Rectd& instance) { switch (lua.GetType(2)) { @@ -531,7 +531,7 @@ namespace Ndk /*********************************** Nz::Quaternion **********************************/ quaternion.Reset("Quaternion"); { - quaternion.SetConstructor([] (Nz::LuaInstance& lua, Nz::Quaterniond* instance, std::size_t argumentCount) + quaternion.SetConstructor([] (Nz::LuaState& lua, Nz::Quaterniond* instance, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 4U); @@ -587,7 +587,7 @@ namespace Ndk quaternion.BindStaticMethod("RotationBetween", &Nz::Quaterniond::RotationBetween); quaternion.BindStaticMethod("Slerp", &Nz::Quaterniond::Slerp); - quaternion.BindMethod("GetNormal", [] (Nz::LuaInstance& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int + quaternion.BindMethod("GetNormal", [] (Nz::LuaState& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int { double length; @@ -597,7 +597,7 @@ namespace Ndk return 2; }); - quaternion.BindMethod("Normalize", [] (Nz::LuaInstance& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int + quaternion.BindMethod("Normalize", [] (Nz::LuaState& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int { double length; @@ -608,20 +608,20 @@ namespace Ndk return 2; }); - quaternion.BindStaticMethod("Normalize", [] (Nz::LuaInstance& instance) -> int + quaternion.BindStaticMethod("Normalize", [] (Nz::LuaState& state) -> int { int argIndex = 1; - Nz::Quaterniond quat = instance.Check(&argIndex); + Nz::Quaterniond quat = state.Check(&argIndex); double length; - instance.Push(Nz::Quaterniond::Normalize(quat, &length)); - instance.Push(length); + state.Push(Nz::Quaterniond::Normalize(quat, &length)); + state.Push(length); return 2; }); - quaternion.SetGetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) + quaternion.SetGetter([] (Nz::LuaState& lua, Nz::Quaterniond& instance) { std::size_t length; const char* wxyz = lua.CheckString(2, &length); @@ -651,7 +651,7 @@ namespace Ndk return false; }); - quaternion.SetSetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) + quaternion.SetSetter([] (Nz::LuaState& lua, Nz::Quaterniond& instance) { std::size_t length; const char* wxyz = lua.CheckString(2, &length); @@ -690,7 +690,7 @@ namespace Ndk /*********************************** Nz::Vector2 **********************************/ vector2d.Reset("Vector2"); { - vector2d.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector2d* vector, std::size_t argumentCount) + vector2d.SetConstructor([] (Nz::LuaState& lua, Nz::Vector2d* vector, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 2U); @@ -720,7 +720,7 @@ namespace Ndk vector2d.BindMethod("__tostring", &Nz::Vector2d::ToString); - vector2d.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector2d& instance) + vector2d.SetGetter([] (Nz::LuaState& lua, Nz::Vector2d& instance) { switch (lua.GetType(2)) { @@ -765,7 +765,7 @@ namespace Ndk return false; }); - vector2d.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector2d& instance) + vector2d.SetSetter([] (Nz::LuaState& lua, Nz::Vector2d& instance) { switch (lua.GetType(2)) { @@ -816,7 +816,7 @@ namespace Ndk /*********************************** Nz::Vector3 **********************************/ vector3d.Reset("Vector3"); { - vector3d.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector3d* vector, std::size_t argumentCount) + vector3d.SetConstructor([] (Nz::LuaState& lua, Nz::Vector3d* vector, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 3U); @@ -860,7 +860,7 @@ namespace Ndk vector3d.BindMethod("__tostring", &Nz::Vector3d::ToString); - vector3d.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) + vector3d.SetGetter([] (Nz::LuaState& lua, Nz::Vector3d& instance) { switch (lua.GetType(2)) { @@ -909,7 +909,7 @@ namespace Ndk return false; }); - vector3d.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance) + vector3d.SetSetter([] (Nz::LuaState& lua, Nz::Vector3d& instance) { switch (lua.GetType(2)) { @@ -967,20 +967,20 @@ namespace Ndk * * \param instance Lua instance that will interact with the Math classes */ - void LuaBinding_Math::Register(Nz::LuaInstance& instance) + void LuaBinding_Math::Register(Nz::LuaState& state) { - eulerAngles.Register(instance); - matrix4d.Register(instance); - quaternion.Register(instance); - rect.Register(instance); - vector2d.Register(instance); - vector3d.Register(instance); + eulerAngles.Register(state); + matrix4d.Register(state); + quaternion.Register(state); + rect.Register(state); + vector2d.Register(state); + vector3d.Register(state); - quaternion.PushGlobalTable(instance); + quaternion.PushGlobalTable(state); { - instance.PushField("Identity", Nz::Quaterniond::Identity()); - instance.PushField("Zero", Nz::Quaterniond::Zero()); + state.PushField("Identity", Nz::Quaterniond::Identity()); + state.PushField("Zero", Nz::Quaterniond::Zero()); } - instance.Pop(); + state.Pop(); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Network.cpp b/SDK/src/NDK/Lua/LuaBinding_Network.cpp index d6f92cb40..c54ef89a0 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Network.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Network.cpp @@ -28,11 +28,11 @@ namespace Ndk /*********************************** Nz::IpAddress **********************************/ ipAddress.Reset("IpAddress"); { - ipAddress.SetConstructor([] (Nz::LuaInstance& lua, Nz::IpAddress* instance, std::size_t argumentCount) + ipAddress.SetConstructor([] (Nz::LuaState& lua, Nz::IpAddress* instance, std::size_t argumentCount) { std::size_t argCount = std::min(argumentCount, 9U); - int argIndex = 2; + int argIndex = 1; switch (argCount) { case 0: @@ -85,63 +85,120 @@ namespace Ndk ipAddress.BindMethod("ToUInt32", &Nz::IpAddress::ToUInt32); ipAddress.BindMethod("__tostring", &Nz::IpAddress::ToString); - ipAddress.BindStaticMethod("ResolveAddress", [] (Nz::LuaInstance& instance) -> int + ipAddress.BindStaticMethod("ResolveAddress", [] (Nz::LuaState& state) -> int { Nz::String service; Nz::ResolveError error = Nz::ResolveError_Unknown; int argIndex = 2; - Nz::String hostName = Nz::IpAddress::ResolveAddress(instance.Check(&argIndex), &service, &error); + Nz::String hostName = Nz::IpAddress::ResolveAddress(state.Check(&argIndex), &service, &error); if (error == Nz::ResolveError_NoError) { - instance.Push(hostName); - instance.Push(service); + state.Push(hostName); + state.Push(service); return 2; } else { - instance.PushBoolean(false); - instance.Push(error); + state.PushBoolean(false); + state.Push(error); return 2; } }); - ipAddress.BindStaticMethod("ResolveHostname", [] (Nz::LuaInstance& instance) -> int + ipAddress.BindStaticMethod("ResolveHostname", [] (Nz::LuaState& state) -> int { Nz::ResolveError error = Nz::ResolveError_Unknown; int argIndex = 2; - Nz::NetProtocol protocol = instance.Check(&argIndex); - Nz::String hostname = instance.Check(&argIndex); - Nz::String service = instance.Check(&argIndex, "http"); + Nz::NetProtocol protocol = state.Check(&argIndex); + Nz::String hostname = state.Check(&argIndex); + Nz::String service = state.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()); + state.PushTable(addresses.size()); for (Nz::HostnameInfo& info : addresses) { - instance.PushInteger(index++); - instance.PushTable(0, 4); - instance.PushField("Address", std::move(info.address)); - instance.PushField("CanonicalName", std::move(info.canonicalName)); - instance.PushField("Protocol", std::move(info.protocol)); - instance.PushField("SocketType", std::move(info.socketType)); - instance.SetTable(); + state.PushInteger(index++); + state.PushTable(0, 4); + state.PushField("Address", std::move(info.address)); + state.PushField("CanonicalName", std::move(info.canonicalName)); + state.PushField("Protocol", std::move(info.protocol)); + state.PushField("SocketType", std::move(info.socketType)); + state.SetTable(); } return 1; } else { - instance.PushBoolean(false); - instance.Push(error); + state.PushBoolean(false); + state.Push(error); return 2; } }); } + + udpSocket.Reset("UdpSocket"); + { + udpSocket.Inherit(abstractSocket); + + udpSocket.BindDefaultConstructor(); + + udpSocket.BindMethod("Create", &Nz::UdpSocket::Create); + udpSocket.BindMethod("EnableBroadcasting", &Nz::UdpSocket::EnableBroadcasting); + udpSocket.BindMethod("GetBoundAddress", &Nz::UdpSocket::GetBoundAddress); + udpSocket.BindMethod("GetBoundPort", &Nz::UdpSocket::GetBoundPort); + udpSocket.BindMethod("IsBroadcastingEnabled", &Nz::UdpSocket::IsBroadcastingEnabled); + udpSocket.BindMethod("QueryMaxDatagramSize", &Nz::UdpSocket::QueryMaxDatagramSize); + + udpSocket.BindMethod("Bind", [](Nz::LuaState& lua, Nz::UdpSocket& socket, std::size_t /*argumentCount*/) -> int + { + int argIndex = 2; + if (lua.IsOfType(argIndex, "IpAddress")) + return lua.Push(socket.Bind(*static_cast(lua.ToUserdata(argIndex)))); + else + return lua.Push(socket.Bind(lua.Check(&argIndex))); + }); + + udpSocket.BindMethod("Receive", [](Nz::LuaState& lua, Nz::UdpSocket& socket, std::size_t /*argumentCount*/) -> int + { + Nz::IpAddress from; + + std::array buffer; + std::size_t received; + if (socket.Receive(buffer.data(), buffer.size(), &from, &received)) + { + lua.PushBoolean(true); + lua.PushString(from.ToString()); + lua.PushString(buffer.data(), received); + return 3; + } + + lua.PushBoolean(false); + return 1; + }); + + udpSocket.BindMethod("Send", [](Nz::LuaState& lua, Nz::UdpSocket& socket, std::size_t /*argumentCount*/) -> int + { + int argIndex = 2; + Nz::String to = lua.Check(&argIndex); + + std::size_t bufferLength; + const char* buffer = lua.CheckString(argIndex, &bufferLength); + + std::size_t sent; + bool ret; + if ((ret = socket.Send(Nz::IpAddress(to), buffer, bufferLength, &sent)) != true) + sent = 0; + + return lua.Push(std::make_pair(ret, sent)); + }); + } } /*! @@ -149,107 +206,108 @@ namespace Ndk * * \param instance Lua instance that will interact with the Network classes */ - void LuaBinding_Network::Register(Nz::LuaInstance& instance) + void LuaBinding_Network::Register(Nz::LuaState& state) { // Classes - abstractSocket.Register(instance); - ipAddress.Register(instance); + abstractSocket.Register(state); + ipAddress.Register(state); + udpSocket.Register(state); // 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); + state.PushTable(0, 4); { - instance.PushField("Any", Nz::NetProtocol_Any); - instance.PushField("IPv4", Nz::NetProtocol_IPv4); - instance.PushField("IPv6", Nz::NetProtocol_IPv6); - instance.PushField("Unknown", Nz::NetProtocol_Unknown); + state.PushField("Any", Nz::NetProtocol_Any); + state.PushField("IPv4", Nz::NetProtocol_IPv4); + state.PushField("IPv6", Nz::NetProtocol_IPv6); + state.PushField("Unknown", Nz::NetProtocol_Unknown); } - instance.SetGlobal("NetProtocol"); + state.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); + state.PushTable(0, 6); { - instance.PushField("High", Nz::PacketPriority_High); - instance.PushField("Highest", Nz::PacketPriority_Highest); - instance.PushField("Immediate", Nz::PacketPriority_Immediate); - instance.PushField("Medium", Nz::PacketPriority_Medium); - instance.PushField("Low", Nz::PacketPriority_Low); - instance.PushField("Lowest", Nz::PacketPriority_Lowest); + state.PushField("High", Nz::PacketPriority_High); + state.PushField("Highest", Nz::PacketPriority_Highest); + state.PushField("Immediate", Nz::PacketPriority_Immediate); + state.PushField("Medium", Nz::PacketPriority_Medium); + state.PushField("Low", Nz::PacketPriority_Low); + state.PushField("Lowest", Nz::PacketPriority_Lowest); } - instance.SetGlobal("PacketPriority"); + state.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); + state.PushTable(0, 3); { - instance.PushField("Reliable", Nz::PacketReliability_Reliable); - instance.PushField("ReliableOrdered", Nz::PacketReliability_ReliableOrdered); - instance.PushField("Unreliable", Nz::PacketReliability_Unreliable); + state.PushField("Reliable", Nz::PacketReliability_Reliable); + state.PushField("ReliableOrdered", Nz::PacketReliability_ReliableOrdered); + state.PushField("Unreliable", Nz::PacketReliability_Unreliable); } - instance.SetGlobal("PacketReliability"); + state.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); + state.PushTable(0, 9); { - instance.PushField("Internal", Nz::ResolveError_Internal); - instance.PushField("ResourceError", Nz::ResolveError_ResourceError); - instance.PushField("NoError", Nz::ResolveError_NoError); - instance.PushField("NonRecoverable", Nz::ResolveError_NonRecoverable); - instance.PushField("NotFound", Nz::ResolveError_NotFound); - instance.PushField("NotInitialized", Nz::ResolveError_NotInitialized); - instance.PushField("ProtocolNotSupported", Nz::ResolveError_ProtocolNotSupported); - instance.PushField("TemporaryFailure", Nz::ResolveError_TemporaryFailure); - instance.PushField("Unknown", Nz::ResolveError_Unknown); + state.PushField("Internal", Nz::ResolveError_Internal); + state.PushField("ResourceError", Nz::ResolveError_ResourceError); + state.PushField("NoError", Nz::ResolveError_NoError); + state.PushField("NonRecoverable", Nz::ResolveError_NonRecoverable); + state.PushField("NotFound", Nz::ResolveError_NotFound); + state.PushField("NotInitialized", Nz::ResolveError_NotInitialized); + state.PushField("ProtocolNotSupported", Nz::ResolveError_ProtocolNotSupported); + state.PushField("TemporaryFailure", Nz::ResolveError_TemporaryFailure); + state.PushField("Unknown", Nz::ResolveError_Unknown); } - instance.SetGlobal("ResolveError"); + state.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); + state.PushTable(0, 15); { - instance.PushField("AddressNotAvailable", Nz::SocketError_AddressNotAvailable); - instance.PushField("ConnectionClosed", Nz::SocketError_ConnectionClosed); - instance.PushField("ConnectionRefused", Nz::SocketError_ConnectionRefused); - instance.PushField("DatagramSize", Nz::SocketError_DatagramSize); - instance.PushField("Internal", Nz::SocketError_Internal); - instance.PushField("Packet", Nz::SocketError_Packet); - instance.PushField("NetworkError", Nz::SocketError_NetworkError); - instance.PushField("NoError", Nz::SocketError_NoError); - instance.PushField("NotInitialized", Nz::SocketError_NotInitialized); - instance.PushField("NotSupported", Nz::SocketError_NotSupported); - instance.PushField("ResolveError", Nz::SocketError_ResolveError); - instance.PushField("ResourceError", Nz::SocketError_ResourceError); - instance.PushField("TimedOut", Nz::SocketError_TimedOut); - instance.PushField("Unknown", Nz::SocketError_Unknown); - instance.PushField("UnreachableHost", Nz::SocketError_UnreachableHost); + state.PushField("AddressNotAvailable", Nz::SocketError_AddressNotAvailable); + state.PushField("ConnectionClosed", Nz::SocketError_ConnectionClosed); + state.PushField("ConnectionRefused", Nz::SocketError_ConnectionRefused); + state.PushField("DatagramSize", Nz::SocketError_DatagramSize); + state.PushField("Internal", Nz::SocketError_Internal); + state.PushField("Packet", Nz::SocketError_Packet); + state.PushField("NetworkError", Nz::SocketError_NetworkError); + state.PushField("NoError", Nz::SocketError_NoError); + state.PushField("NotInitialized", Nz::SocketError_NotInitialized); + state.PushField("NotSupported", Nz::SocketError_NotSupported); + state.PushField("ResolveError", Nz::SocketError_ResolveError); + state.PushField("ResourceError", Nz::SocketError_ResourceError); + state.PushField("TimedOut", Nz::SocketError_TimedOut); + state.PushField("Unknown", Nz::SocketError_Unknown); + state.PushField("UnreachableHost", Nz::SocketError_UnreachableHost); } - instance.SetGlobal("SocketError"); + state.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); + state.PushTable(0, 5); { - instance.PushField("Bound", Nz::SocketState_Bound); - instance.PushField("Connecting", Nz::SocketState_Connecting); - instance.PushField("Connected", Nz::SocketState_Connected); - instance.PushField("NotConnected", Nz::SocketState_NotConnected); - instance.PushField("Resolving", Nz::SocketState_Resolving); + state.PushField("Bound", Nz::SocketState_Bound); + state.PushField("Connecting", Nz::SocketState_Connecting); + state.PushField("Connected", Nz::SocketState_Connected); + state.PushField("NotConnected", Nz::SocketState_NotConnected); + state.PushField("Resolving", Nz::SocketState_Resolving); } - instance.SetGlobal("SocketState"); + state.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); + state.PushTable(0, 4); { - instance.PushField("Raw", Nz::SocketType_Raw); - instance.PushField("TCP", Nz::SocketType_TCP); - instance.PushField("UDP", Nz::SocketType_UDP); - instance.PushField("Unknown", Nz::SocketType_Unknown); + state.PushField("Raw", Nz::SocketType_Raw); + state.PushField("TCP", Nz::SocketType_TCP); + state.PushField("UDP", Nz::SocketType_UDP); + state.PushField("Unknown", Nz::SocketType_Unknown); } - instance.SetGlobal("SocketType"); + state.SetGlobal("SocketType"); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp b/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp index 7f881e20d..1ab24cedb 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot +// Copyright (C) 2017 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 @@ -27,7 +27,7 @@ namespace Ndk return reinterpret_cast(textureRef); //TODO: Make a ObjectRefCast }); - texture.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::TextureRef* instance, std::size_t /*argumentCount*/) + texture.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::TextureRef* instance, std::size_t /*argumentCount*/) { Nz::PlacementNew(instance, Nz::Texture::New()); return true; @@ -84,7 +84,7 @@ namespace Ndk } /*********************************** Nz::TextureManager ***********************************/ - textureManager.Reset("textureManager"); + textureManager.Reset("TextureManager"); { textureManager.BindStaticMethod("Clear", &Nz::TextureManager::Clear); textureManager.BindStaticMethod("Get", &Nz::TextureManager::Get); @@ -101,10 +101,10 @@ namespace Ndk * * \param instance Lua instance that will interact with the Renderer classes */ - void LuaBinding_Renderer::Register(Nz::LuaInstance& instance) + void LuaBinding_Renderer::Register(Nz::LuaState& state) { - texture.Register(instance); - textureLibrary.Register(instance); - textureManager.Register(instance); + texture.Register(state); + textureLibrary.Register(state); + textureManager.Register(state); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_SDK.cpp b/SDK/src/NDK/Lua/LuaBinding_SDK.cpp index ad9bb49e9..8952ce7d9 100644 --- a/SDK/src/NDK/Lua/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_SDK.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot +// Copyright (C) 2017 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 @@ -40,7 +40,7 @@ namespace Ndk application.BindMethod("IsFPSCounterEnabled", &Application::IsFPSCounterEnabled); #endif - application.BindMethod("AddWorld", [] (Nz::LuaInstance& lua, Application* instance, std::size_t /*argumentCount*/) -> int + application.BindMethod("AddWorld", [] (Nz::LuaState& lua, Application* instance, std::size_t /*argumentCount*/) -> int { lua.Push(instance->AddWorld().CreateHandle()); return 1; @@ -69,6 +69,7 @@ namespace Ndk console.BindMethod("GetSize", &Console::GetSize); console.BindMethod("GetTextFont", &Console::GetTextFont); + console.BindMethod("IsValidHandle", &ConsoleHandle::IsValid); console.BindMethod("IsVisible", &Console::IsVisible); console.BindMethod("SendCharacter", &Console::SendCharacter); @@ -91,28 +92,37 @@ namespace Ndk entity.BindMethod("Kill", &Entity::Kill); entity.BindMethod("IsEnabled", &Entity::IsEnabled); entity.BindMethod("IsValid", &Entity::IsValid); + entity.BindMethod("IsValidHandle", &EntityHandle::IsValid); entity.BindMethod("RemoveAllComponents", &Entity::RemoveAllComponents); entity.BindMethod("__tostring", &EntityHandle::ToString); - entity.BindMethod("AddComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle, std::size_t /*argumentCount*/) -> int + entity.BindMethod("AddComponent", [this] (Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int { - LuaBinding::ComponentBinding* binding = m_binding.QueryComponentIndex(instance); + LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state); - return binding->adder(instance, handle); + return bindingComponent->adder(state, handle); }); - entity.BindMethod("GetComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle, std::size_t /*argumentCount*/) -> int + entity.BindMethod("HasComponent", [this](Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int { - LuaBinding::ComponentBinding* binding = m_binding.QueryComponentIndex(instance); + LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state); - return binding->getter(instance, handle->GetComponent(binding->index)); + state.PushBoolean(handle->HasComponent(bindingComponent->index)); + return 1; }); - entity.BindMethod("RemoveComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle, std::size_t /*argumentCount*/) -> int + entity.BindMethod("GetComponent", [this] (Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int { - LuaBinding::ComponentBinding* binding = m_binding.QueryComponentIndex(instance); + LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state); - handle->RemoveComponent(binding->index); + return bindingComponent->getter(state, handle->GetComponent(bindingComponent->index)); + }); + + entity.BindMethod("RemoveComponent", [this] (Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int + { + LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state); + + handle->RemoveComponent(bindingComponent->index); return 0; }); } @@ -120,6 +130,8 @@ namespace Ndk /*********************************** Ndk::NodeComponent **********************************/ nodeComponent.Reset("NodeComponent"); { + nodeComponent.BindMethod("IsValidHandle", &NodeComponentHandle::IsValid); + nodeComponent.Inherit(utility.node, [] (NodeComponentHandle* handle) -> Nz::Node* { return handle->GetObject(); @@ -129,7 +141,9 @@ namespace Ndk /*********************************** Ndk::VelocityComponent **********************************/ velocityComponent.Reset("VelocityComponent"); { - velocityComponent.SetGetter([] (Nz::LuaInstance& lua, VelocityComponentHandle& instance) + velocityComponent.BindMethod("IsValidHandle", &VelocityComponentHandle::IsValid); + + velocityComponent.SetGetter([] (Nz::LuaState& lua, VelocityComponentHandle& instance) { std::size_t length; const char* member = lua.CheckString(2, &length); @@ -143,7 +157,7 @@ namespace Ndk return false; }); - velocityComponent.SetSetter([] (Nz::LuaInstance& lua, VelocityComponentHandle& instance) + velocityComponent.SetSetter([] (Nz::LuaState& lua, VelocityComponentHandle& instance) { std::size_t length; const char* member = lua.CheckString(2, &length); @@ -165,6 +179,8 @@ namespace Ndk world.BindMethod("CreateEntity", &World::CreateEntity); world.BindMethod("CreateEntities", &World::CreateEntities); world.BindMethod("Clear", &World::Clear); + + world.BindMethod("IsValidHandle", &WorldHandle::IsValid); } #ifndef NDK_SERVER @@ -176,24 +192,26 @@ namespace Ndk return handle->GetObject(); }); - cameraComponent.BindMethod("GetFOV", &Ndk::CameraComponent::GetFOV); - cameraComponent.BindMethod("GetLayer", &Ndk::CameraComponent::GetLayer); + cameraComponent.BindMethod("GetFOV", &CameraComponent::GetFOV); + cameraComponent.BindMethod("GetLayer", &CameraComponent::GetLayer); - cameraComponent.BindMethod("SetFOV", &Ndk::CameraComponent::SetFOV); - cameraComponent.BindMethod("SetLayer", &Ndk::CameraComponent::SetLayer); - cameraComponent.BindMethod("SetProjectionType", &Ndk::CameraComponent::SetProjectionType); - cameraComponent.BindMethod("SetSize", (void(Ndk::CameraComponent::*)(const Nz::Vector2f&)) &Ndk::CameraComponent::SetSize); - //cameraComponent.BindMethod("SetTarget", &Ndk::CameraComponent::SetTarget); - cameraComponent.BindMethod("SetTargetRegion", &Ndk::CameraComponent::SetTargetRegion); - cameraComponent.BindMethod("SetViewport", &Ndk::CameraComponent::SetViewport); - cameraComponent.BindMethod("SetZFar", &Ndk::CameraComponent::SetZFar); - cameraComponent.BindMethod("SetZNear", &Ndk::CameraComponent::SetZNear); + cameraComponent.BindMethod("IsValidHandle", &CameraComponentHandle::IsValid); + + cameraComponent.BindMethod("SetFOV", &CameraComponent::SetFOV); + cameraComponent.BindMethod("SetLayer", &CameraComponent::SetLayer); + cameraComponent.BindMethod("SetProjectionType", &CameraComponent::SetProjectionType); + cameraComponent.BindMethod("SetSize", (void(CameraComponent::*)(const Nz::Vector2f&)) &CameraComponent::SetSize); + //cameraComponent.BindMethod("SetTarget", &CameraComponent::SetTarget); + cameraComponent.BindMethod("SetTargetRegion", &CameraComponent::SetTargetRegion); + cameraComponent.BindMethod("SetViewport", &CameraComponent::SetViewport); + cameraComponent.BindMethod("SetZFar", &CameraComponent::SetZFar); + cameraComponent.BindMethod("SetZNear", &CameraComponent::SetZNear); } /*********************************** Ndk::GraphicsComponent **********************************/ graphicsComponent.Reset("GraphicsComponent"); { - graphicsComponent.BindMethod("Attach", [] (Nz::LuaInstance& lua, Ndk::GraphicsComponent* instance, std::size_t argumentCount) -> int + graphicsComponent.BindMethod("Attach", [] (Nz::LuaState& lua, Ndk::GraphicsComponent* instance, std::size_t argumentCount) -> int { /* void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); @@ -249,6 +267,8 @@ namespace Ndk lua.Error("No matching overload for method GetMemoryUsage"); return 0; }); + + graphicsComponent.BindMethod("IsValidHandle", &GraphicsComponentHandle::IsValid); } #endif @@ -267,19 +287,19 @@ namespace Ndk * * \param instance Lua instance that will interact with the SDK classes */ - void LuaBinding_SDK::Register(Nz::LuaInstance& instance) + void LuaBinding_SDK::Register(Nz::LuaState& state) { // Classes - application.Register(instance); - entity.Register(instance); - nodeComponent.Register(instance); - velocityComponent.Register(instance); - world.Register(instance); + application.Register(state); + entity.Register(state); + nodeComponent.Register(state); + velocityComponent.Register(state); + world.Register(state); #ifndef NDK_SERVER - cameraComponent.Register(instance); - console.Register(instance); - graphicsComponent.Register(instance); + cameraComponent.Register(state); + console.Register(state); + graphicsComponent.Register(state); #endif // Enums @@ -292,23 +312,23 @@ namespace Ndk * \param instance Lua instance that will interact with the component * \param argIndex Index of the component */ - LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaInstance& instance, int argIndex) + LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaState& state, int argIndex) { - switch (instance.GetType(argIndex)) + switch (state.GetType(argIndex)) { case Nz::LuaType_Number: { - ComponentIndex componentIndex = instance.Check(&argIndex); + ComponentIndex componentIndex = state.Check(&argIndex); if (componentIndex > m_componentBinding.size()) { - instance.Error("Invalid component index"); + state.Error("Invalid component index"); return nullptr; } ComponentBinding& binding = m_componentBinding[componentIndex]; if (binding.name.IsEmpty()) { - instance.Error("Invalid component index"); + state.Error("Invalid component index"); return nullptr; } @@ -317,11 +337,11 @@ namespace Ndk case Nz::LuaType_String: { - const char* key = instance.CheckString(argIndex); + const char* key = state.CheckString(argIndex); auto it = m_componentBindingByName.find(key); if (it == m_componentBindingByName.end()) { - instance.Error("Invalid component name"); + state.Error("Invalid component name"); return nullptr; } @@ -332,7 +352,7 @@ namespace Ndk break; } - instance.Error("Invalid component index at #" + Nz::String::Number(argIndex)); + state.Error("Invalid component index at #" + Nz::String::Number(argIndex)); return nullptr; } } diff --git a/SDK/src/NDK/Lua/LuaBinding_Utility.cpp b/SDK/src/NDK/Lua/LuaBinding_Utility.cpp index 173d6c3c5..6d7baf588 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Utility.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Utility.cpp @@ -29,7 +29,7 @@ namespace Ndk abstractImage.BindMethod("IsCompressed", &Nz::AbstractImage::IsCompressed); abstractImage.BindMethod("IsCubemap", &Nz::AbstractImage::IsCubemap); - abstractImage.BindMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int + abstractImage.BindMethod("GetMemoryUsage", [] (Nz::LuaState& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 1U); switch (argCount) @@ -50,7 +50,7 @@ namespace Ndk return 0; }); - abstractImage.BindMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int + abstractImage.BindMethod("Update", [] (Nz::LuaState& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 6U); int argIndex = 2; @@ -100,7 +100,7 @@ namespace Ndk /*********************************** Nz::Font **********************************/ font.Reset("Font"); { - font.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::FontRef* instance, std::size_t /*argumentCount*/) + font.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::FontRef* instance, std::size_t /*argumentCount*/) { Nz::PlacementNew(instance, Nz::Font::New()); return true; @@ -112,7 +112,7 @@ namespace Ndk font.BindMethod("Destroy", &Nz::Font::Destroy); - font.BindMethod("GetCachedGlyphCount", [] (Nz::LuaInstance& lua, Nz::FontRef& instance, std::size_t argumentCount) -> int + font.BindMethod("GetCachedGlyphCount", [] (Nz::LuaState& lua, Nz::FontRef& instance, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 2U); @@ -216,29 +216,29 @@ namespace Ndk node.BindMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local); node.BindMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local); - node.BindMethod("Move", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t /*argumentCount*/) -> int + node.BindMethod("Move", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t /*argumentCount*/) -> int { int argIndex = 2; Nz::Vector3f offset = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - instance.Move(offset, coordSys); + node.Move(offset, coordSys); return 0; }); - node.BindMethod("Rotate", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t /*argumentCount*/) -> int + node.BindMethod("Rotate", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t /*argumentCount*/) -> int { int argIndex = 2; Nz::Quaternionf rotation = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - instance.Rotate(rotation, coordSys); + node.Rotate(rotation, coordSys); return 0; }); - node.BindMethod("Scale", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t argumentCount) -> int + node.BindMethod("Scale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 4U); @@ -248,15 +248,15 @@ namespace Ndk case 1: { if (lua.IsOfType(argIndex, Nz::LuaType_Number)) - instance.Scale(lua.Check(&argIndex)); + node.Scale(lua.Check(&argIndex)); else - instance.Scale(lua.Check(&argIndex)); + node.Scale(lua.Check(&argIndex)); return 0; } case 3: - instance.Scale(lua.Check(&argIndex)); + node.Scale(lua.Check(&argIndex)); return 0; } @@ -264,7 +264,7 @@ namespace Ndk return 0; }); - node.BindMethod("SetScale", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t argumentCount) -> int + node.BindMethod("SetScale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 4U); @@ -278,10 +278,10 @@ namespace Ndk { float scale = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - instance.SetScale(scale, coordSys); + node.SetScale(scale, coordSys); } else - instance.SetScale(lua.Check(&argIndex)); + node.SetScale(lua.Check(&argIndex)); return 0; } @@ -292,7 +292,7 @@ namespace Ndk Nz::Vector3f scale = lua.Check(&argIndex); Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); - instance.SetScale(scale, coordSys); + node.SetScale(scale, coordSys); return 0; } } @@ -301,7 +301,7 @@ namespace Ndk return 0; }); - node.BindMethod("SetInitialScale", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t argumentCount) -> int + node.BindMethod("SetInitialScale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int { std::size_t argCount = std::min(argumentCount, 4U); @@ -311,16 +311,16 @@ namespace Ndk case 1: { if (lua.IsOfType(argIndex, Nz::LuaType_Number)) - instance.SetInitialScale(lua.Check(&argIndex)); + node.SetInitialScale(lua.Check(&argIndex)); else - instance.SetInitialScale(lua.Check(&argIndex)); + node.SetInitialScale(lua.Check(&argIndex)); return 0; } case 2: case 3: - instance.SetInitialScale(lua.Check(&argIndex)); + node.SetInitialScale(lua.Check(&argIndex)); return 0; } @@ -335,112 +335,110 @@ namespace Ndk * * \param instance Lua instance that will interact with the Utility classes */ - void LuaBinding_Utility::Register(Nz::LuaInstance& instance) + void LuaBinding_Utility::Register(Nz::LuaState& state) { - abstractImage.Register(instance); - font.Register(instance); - keyboard.Register(instance); - node.Register(instance); + abstractImage.Register(state); + font.Register(state); + keyboard.Register(state); + node.Register(state); - keyboard.PushGlobalTable(instance); + keyboard.PushGlobalTable(state); { static_assert(Nz::Keyboard::Count == 121, "Nz::Keyboard::Key has been updated but change was not reflected to Lua binding"); - instance.PushField("Undefined", Nz::Keyboard::Undefined); + state.PushField("Undefined", Nz::Keyboard::Undefined); // A-Z for (std::size_t i = 0; i < 26; ++i) - instance.PushField(Nz::String('A' + char(i)), Nz::Keyboard::A + i); + state.PushField(Nz::String('A' + char(i)), Nz::Keyboard::A + i); // Numerical for (std::size_t i = 0; i < 10; ++i) { - instance.PushField("Num" + Nz::String::Number(i), Nz::Keyboard::Num0 + i); - instance.PushField("Numpad" + Nz::String::Number(i), Nz::Keyboard::Numpad0 + i); + state.PushField("Num" + Nz::String::Number(i), Nz::Keyboard::Num0 + i); + state.PushField("Numpad" + Nz::String::Number(i), Nz::Keyboard::Numpad0 + i); } // F1-F15 for (std::size_t i = 0; i < 15; ++i) - instance.PushField('F' + Nz::String::Number(i+1), Nz::Keyboard::F1 + i); + state.PushField('F' + Nz::String::Number(i+1), Nz::Keyboard::F1 + i); // And all the others... - instance.PushField("Down", Nz::Keyboard::Down); - instance.PushField("Left", Nz::Keyboard::Left); - instance.PushField("Right", Nz::Keyboard::Right); - instance.PushField("Up", Nz::Keyboard::Up); + state.PushField("Down", Nz::Keyboard::Down); + state.PushField("Left", Nz::Keyboard::Left); + state.PushField("Right", Nz::Keyboard::Right); + state.PushField("Up", Nz::Keyboard::Up); - instance.PushField("Add", Nz::Keyboard::Add); - instance.PushField("Decimal", Nz::Keyboard::Decimal); - instance.PushField("Divide", Nz::Keyboard::Divide); - instance.PushField("Multiply", Nz::Keyboard::Multiply); - instance.PushField("Subtract", Nz::Keyboard::Subtract); + state.PushField("Add", Nz::Keyboard::Add); + state.PushField("Decimal", Nz::Keyboard::Decimal); + state.PushField("Divide", Nz::Keyboard::Divide); + state.PushField("Multiply", Nz::Keyboard::Multiply); + state.PushField("Subtract", Nz::Keyboard::Subtract); - instance.PushField("Backslash", Nz::Keyboard::Backslash); - instance.PushField("Backspace", Nz::Keyboard::Backspace); - instance.PushField("Clear", Nz::Keyboard::Clear); - instance.PushField("Comma", Nz::Keyboard::Comma); - instance.PushField("Dash", Nz::Keyboard::Dash); - instance.PushField("Delete", Nz::Keyboard::Delete); - instance.PushField("End", Nz::Keyboard::End); - instance.PushField("Equal", Nz::Keyboard::Equal); - instance.PushField("Escape", Nz::Keyboard::Escape); - instance.PushField("Home", Nz::Keyboard::Home); - instance.PushField("Insert", Nz::Keyboard::Insert); - instance.PushField("LAlt", Nz::Keyboard::LAlt); - instance.PushField("LBracket", Nz::Keyboard::LBracket); - instance.PushField("LControl", Nz::Keyboard::LControl); - instance.PushField("LShift", Nz::Keyboard::LShift); - instance.PushField("LSystem", Nz::Keyboard::LSystem); - instance.PushField("PageDown", Nz::Keyboard::PageDown); - instance.PushField("PageUp", Nz::Keyboard::PageUp); - instance.PushField("Pause", Nz::Keyboard::Pause); - instance.PushField("Period", Nz::Keyboard::Period); - instance.PushField("Print", Nz::Keyboard::Print); - instance.PushField("PrintScreen", Nz::Keyboard::PrintScreen); - instance.PushField("Quote", Nz::Keyboard::Quote); - instance.PushField("RAlt", Nz::Keyboard::RAlt); - instance.PushField("RBracket", Nz::Keyboard::RBracket); - instance.PushField("RControl", Nz::Keyboard::RControl); - instance.PushField("Return", Nz::Keyboard::Return); - instance.PushField("RShift", Nz::Keyboard::RShift); - instance.PushField("RSystem", Nz::Keyboard::RSystem); - instance.PushField("Semicolon", Nz::Keyboard::Semicolon); - instance.PushField("Slash", Nz::Keyboard::Slash); - instance.PushField("Space", Nz::Keyboard::Space); - instance.PushField("Tab", Nz::Keyboard::Tab); - instance.PushField("Tilde", Nz::Keyboard::Tilde); - instance.PushField("Browser_Back", Nz::Keyboard::Browser_Back); - instance.PushField("Browser_Favorites", Nz::Keyboard::Browser_Favorites); - instance.PushField("Browser_Forward", Nz::Keyboard::Browser_Forward); - instance.PushField("Browser_Home", Nz::Keyboard::Browser_Home); - instance.PushField("Browser_Refresh", Nz::Keyboard::Browser_Refresh); - instance.PushField("Browser_Search", Nz::Keyboard::Browser_Search); - instance.PushField("Browser_Stop", Nz::Keyboard::Browser_Stop); - instance.PushField("Media_Next", Nz::Keyboard::Media_Next); - instance.PushField("Media_Play", Nz::Keyboard::Media_Play); - instance.PushField("Media_Previous", Nz::Keyboard::Media_Previous); - instance.PushField("Media_Stop", Nz::Keyboard::Media_Stop); - instance.PushField("Volume_Down", Nz::Keyboard::Volume_Down); - instance.PushField("Volume_Mute", Nz::Keyboard::Volume_Mute); - instance.PushField("Volume_Up", Nz::Keyboard::Volume_Up); - instance.PushField("CapsLock", Nz::Keyboard::CapsLock); - instance.PushField("NumLock", Nz::Keyboard::NumLock); - instance.PushField("ScrollLock", Nz::Keyboard::ScrollLock); + state.PushField("Backslash", Nz::Keyboard::Backslash); + state.PushField("Backspace", Nz::Keyboard::Backspace); + state.PushField("Clear", Nz::Keyboard::Clear); + state.PushField("Comma", Nz::Keyboard::Comma); + state.PushField("Dash", Nz::Keyboard::Dash); + state.PushField("Delete", Nz::Keyboard::Delete); + state.PushField("End", Nz::Keyboard::End); + state.PushField("Equal", Nz::Keyboard::Equal); + state.PushField("Escape", Nz::Keyboard::Escape); + state.PushField("Home", Nz::Keyboard::Home); + state.PushField("Insert", Nz::Keyboard::Insert); + state.PushField("LAlt", Nz::Keyboard::LAlt); + state.PushField("LBracket", Nz::Keyboard::LBracket); + state.PushField("LControl", Nz::Keyboard::LControl); + state.PushField("LShift", Nz::Keyboard::LShift); + state.PushField("LSystem", Nz::Keyboard::LSystem); + state.PushField("PageDown", Nz::Keyboard::PageDown); + state.PushField("PageUp", Nz::Keyboard::PageUp); + state.PushField("Pause", Nz::Keyboard::Pause); + state.PushField("Period", Nz::Keyboard::Period); + state.PushField("Print", Nz::Keyboard::Print); + state.PushField("PrintScreen", Nz::Keyboard::PrintScreen); + state.PushField("Quote", Nz::Keyboard::Quote); + state.PushField("RAlt", Nz::Keyboard::RAlt); + state.PushField("RBracket", Nz::Keyboard::RBracket); + state.PushField("RControl", Nz::Keyboard::RControl); + state.PushField("Return", Nz::Keyboard::Return); + state.PushField("RShift", Nz::Keyboard::RShift); + state.PushField("RSystem", Nz::Keyboard::RSystem); + state.PushField("Semicolon", Nz::Keyboard::Semicolon); + state.PushField("Slash", Nz::Keyboard::Slash); + state.PushField("Space", Nz::Keyboard::Space); + state.PushField("Tab", Nz::Keyboard::Tab); + state.PushField("Tilde", Nz::Keyboard::Tilde); + state.PushField("Browser_Back", Nz::Keyboard::Browser_Back); + state.PushField("Browser_Favorites", Nz::Keyboard::Browser_Favorites); + state.PushField("Browser_Forward", Nz::Keyboard::Browser_Forward); + state.PushField("Browser_Home", Nz::Keyboard::Browser_Home); + state.PushField("Browser_Refresh", Nz::Keyboard::Browser_Refresh); + state.PushField("Browser_Search", Nz::Keyboard::Browser_Search); + state.PushField("Browser_Stop", Nz::Keyboard::Browser_Stop); + state.PushField("Media_Next", Nz::Keyboard::Media_Next); + state.PushField("Media_Play", Nz::Keyboard::Media_Play); + state.PushField("Media_Previous", Nz::Keyboard::Media_Previous); + state.PushField("Media_Stop", Nz::Keyboard::Media_Stop); + state.PushField("Volume_Down", Nz::Keyboard::Volume_Down); + state.PushField("Volume_Mute", Nz::Keyboard::Volume_Mute); + state.PushField("Volume_Up", Nz::Keyboard::Volume_Up); + state.PushField("CapsLock", Nz::Keyboard::CapsLock); + state.PushField("NumLock", Nz::Keyboard::NumLock); + state.PushField("ScrollLock", Nz::Keyboard::ScrollLock); } - instance.Pop(); + state.Pop(); static_assert(Nz::WindowStyle_Max + 1 == 6, "Nz::WindowStyle has been updated but change was not reflected to Lua binding"); - instance.PushTable(0, Nz::WindowStyle_Max + 1); + state.PushTable(0, Nz::WindowStyle_Max + 1); { - instance.PushField("None", Nz::WindowStyle_None); - instance.PushField("Fullscreen", Nz::WindowStyle_Fullscreen); - instance.PushField("Closable", Nz::WindowStyle_Closable); - instance.PushField("Resizable", Nz::WindowStyle_Resizable); - instance.PushField("Titlebar", Nz::WindowStyle_Titlebar); - instance.PushField("Threaded", Nz::WindowStyle_Threaded); + state.PushField("None", Nz::WindowStyle_None); + state.PushField("Fullscreen", Nz::WindowStyle_Fullscreen); + state.PushField("Closable", Nz::WindowStyle_Closable); + state.PushField("Resizable", Nz::WindowStyle_Resizable); + state.PushField("Titlebar", Nz::WindowStyle_Titlebar); + state.PushField("Threaded", Nz::WindowStyle_Threaded); } - instance.SetGlobal("WindowStyle"); - - + state.SetGlobal("WindowStyle"); } } diff --git a/SDK/src/NDK/LuaAPI.cpp b/SDK/src/NDK/LuaAPI.cpp index a28fbb05f..3a82d2130 100644 --- a/SDK/src/NDK/LuaAPI.cpp +++ b/SDK/src/NDK/LuaAPI.cpp @@ -44,10 +44,10 @@ namespace Ndk * \param instance Lua instance that will interact with the engine & SDK */ - void LuaAPI::RegisterClasses(Nz::LuaInstance& instance) + void LuaAPI::RegisterClasses(Nz::LuaState& state) { Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true); - GetBinding()->RegisterClasses(instance); + GetBinding()->RegisterClasses(state); } /*! diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 81080af06..312e9a777 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/State.cpp b/SDK/src/NDK/State.cpp index 701b98565..afe0fd708 100644 --- a/SDK/src/NDK/State.cpp +++ b/SDK/src/NDK/State.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Systems/ListenerSystem.cpp b/SDK/src/NDK/Systems/ListenerSystem.cpp index 3de647a08..6c41de58f 100644 --- a/SDK/src/NDK/Systems/ListenerSystem.cpp +++ b/SDK/src/NDK/Systems/ListenerSystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Systems/ParticleSystem.cpp b/SDK/src/NDK/Systems/ParticleSystem.cpp index 9321c0ec2..9a60e0595 100644 --- a/SDK/src/NDK/Systems/ParticleSystem.cpp +++ b/SDK/src/NDK/Systems/ParticleSystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Systems/PhysicsSystem2D.cpp b/SDK/src/NDK/Systems/PhysicsSystem2D.cpp index adedfc170..2616b185f 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem2D.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Systems/PhysicsSystem3D.cpp b/SDK/src/NDK/Systems/PhysicsSystem3D.cpp index c26c932e0..3b4706cc2 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem3D.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index bdbb6cb5b..022621596 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -48,12 +48,14 @@ namespace Ndk { m_forceRenderQueueInvalidation = true; //< Hackfix until lights and particles are handled by culling list - m_cameras.Remove(entity); - m_directionalLights.Remove(entity); - m_drawables.Remove(entity); - m_lights.Remove(entity); - m_particleGroups.Remove(entity); - m_pointSpotLights.Remove(entity); + for (auto it = m_cameras.begin(); it != m_cameras.end(); ++it) + { + if (it->GetObject() == entity) + { + m_cameras.erase(it); + break; + } + } if (entity->HasComponent()) { @@ -74,14 +76,23 @@ namespace Ndk if (entity->HasComponent() && entity->HasComponent()) { - m_cameras.Insert(entity); + m_cameras.emplace_back(entity); std::sort(m_cameras.begin(), m_cameras.end(), [](const EntityHandle& handle1, const EntityHandle& handle2) { return handle1->GetComponent().GetLayer() < handle2->GetComponent().GetLayer(); }); } else - m_cameras.Remove(entity); + { + for (auto it = m_cameras.begin(); it != m_cameras.end(); ++it) + { + if (it->GetObject() == entity) + { + m_cameras.erase(it); + break; + } + } + } if (entity->HasComponent() && entity->HasComponent()) { @@ -181,7 +192,7 @@ namespace Ndk GraphicsComponent& graphicsComponent = drawable->GetComponent(); graphicsComponent.EnsureBoundingVolumeUpdate(); } - + bool forceInvalidation = false; std::size_t visibilityHash = m_drawableCulling.Cull(camComponent.GetFrustum(), &forceInvalidation); diff --git a/SDK/src/NDK/Systems/VelocitySystem.cpp b/SDK/src/NDK/Systems/VelocitySystem.cpp index 02800d716..dddceb2fe 100644 --- a/SDK/src/NDK/Systems/VelocitySystem.cpp +++ b/SDK/src/NDK/Systems/VelocitySystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Widgets/ButtonWidget.cpp b/SDK/src/NDK/Widgets/ButtonWidget.cpp index 25ac74c69..29c04c98f 100644 --- a/SDK/src/NDK/Widgets/ButtonWidget.cpp +++ b/SDK/src/NDK/Widgets/ButtonWidget.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -40,12 +40,14 @@ namespace Ndk { BaseWidget::Layout(); + Nz::Vector2f origin = GetContentOrigin(); const Nz::Vector2f& contentSize = GetContentSize(); + m_gradientEntity->GetComponent().SetPosition(origin); m_gradientSprite->SetSize(contentSize); Nz::Boxf textBox = m_textEntity->GetComponent().GetBoundingVolume().aabb; - m_textEntity->GetComponent().SetPosition(contentSize.x / 2 - textBox.width / 2, contentSize.y / 2 - textBox.height / 2); + m_textEntity->GetComponent().SetPosition(origin.x + contentSize.x / 2 - textBox.width / 2, origin.y + contentSize.y / 2 - textBox.height / 2); } void ButtonWidget::OnMouseButtonRelease(int /*x*/, int /*y*/, Nz::Mouse::Button button) @@ -59,10 +61,7 @@ namespace Ndk m_gradientSprite->SetColor(Nz::Color(128, 128, 128)); } - void ButtonWidget::OnMouseMoved(int x, int y, int deltaX, int deltaY) - { - } - + void ButtonWidget::OnMouseExit() { m_gradientSprite->SetColor(Nz::Color(74, 74, 74)); diff --git a/SDK/src/NDK/Widgets/LabelWidget.cpp b/SDK/src/NDK/Widgets/LabelWidget.cpp index df9c0e1c7..7e4cdf840 100644 --- a/SDK/src/NDK/Widgets/LabelWidget.cpp +++ b/SDK/src/NDK/Widgets/LabelWidget.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 0e0f82f57..932757621 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -18,7 +18,7 @@ namespace Ndk m_readOnly(false) { m_cursorSprite = Nz::Sprite::New(); - m_cursorSprite->SetColor(Nz::Color(192, 192, 192)); + m_cursorSprite->SetColor(Nz::Color::Black); m_cursorSprite->SetSize(1.f, float(m_drawer.GetFont()->GetSizeInfo(m_drawer.GetCharacterSize()).lineHeight)); m_cursorEntity = CreateEntity(); @@ -32,6 +32,8 @@ namespace Ndk m_textEntity->AddComponent().Attach(m_textSprite); m_textEntity->AddComponent().SetParent(this); + SetCursor(Nz::SystemCursor_Text); + Layout(); } @@ -77,13 +79,6 @@ namespace Ndk SetContentSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); } - void TextAreaWidget::SetText(const Nz::String& text) - { - m_drawer.SetText(text); - - m_textSprite->Update(m_drawer); - } - void TextAreaWidget::Write(const Nz::String& text) { if (m_cursorPosition >= m_drawer.GetGlyphCount()) @@ -101,33 +96,13 @@ namespace Ndk } } - void TextAreaWidget::RefreshCursor() + void TextAreaWidget::Layout() { - std::size_t lineCount = m_drawer.GetLineCount(); - std::size_t line = 0U; - for (std::size_t i = line + 1; i < lineCount; ++i) - { - if (m_drawer.GetLine(i).glyphIndex > m_cursorPosition) - break; + BaseWidget::Layout(); - line = i; - } + m_textEntity->GetComponent().SetPosition(GetContentOrigin()); - const auto& lineInfo = m_drawer.GetLine(line); - - std::size_t glyphCount = m_drawer.GetGlyphCount(); - float position; - if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorPosition) - { - const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorPosition, glyphCount - 1)); - position = glyph.bounds.x; - if (m_cursorPosition >= glyphCount) - position += glyph.bounds.width; - } - else - position = 0.f; - - m_cursorEntity->GetComponent().SetPosition(position, lineInfo.bounds.y); + RefreshCursor(); } void TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) @@ -150,13 +125,53 @@ namespace Ndk break; } + case Nz::Keyboard::Down: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyDown(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + break; + + //TODO + break; + } + case Nz::Keyboard::Left: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyLeft(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + break; + MoveCursor(-1); break; + } case Nz::Keyboard::Right: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyRight(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + break; + MoveCursor(1); break; + } + + case Nz::Keyboard::Up: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyUp(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + break; + + //TODO + break; + } } } @@ -197,6 +212,12 @@ namespace Ndk { case '\b': { + bool ignoreDefaultAction = false; + OnTextAreaKeyBackspace(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + break; + const Nz::String& text = m_drawer.GetText(); Nz::String newText; @@ -206,18 +227,23 @@ namespace Ndk if (m_cursorPosition < m_drawer.GetGlyphCount()) newText.Append(text.SubString(text.GetCharacterPosition(m_cursorPosition))); - SetText(newText); MoveCursor(-1); + SetText(newText); break; } case '\r': case '\n': - if (!m_multiLineEnabled) + { + bool ignoreDefaultAction = false; + OnTextAreaKeyReturn(this, &ignoreDefaultAction); + + if (ignoreDefaultAction || !m_multiLineEnabled) break; Write(Nz::String('\n')); break; + } default: { @@ -229,4 +255,35 @@ namespace Ndk } } } + + void TextAreaWidget::RefreshCursor() + { + std::size_t lineCount = m_drawer.GetLineCount(); + std::size_t line = 0U; + for (std::size_t i = line + 1; i < lineCount; ++i) + { + if (m_drawer.GetLine(i).glyphIndex > m_cursorPosition) + break; + + line = i; + } + + const auto& lineInfo = m_drawer.GetLine(line); + + std::size_t glyphCount = m_drawer.GetGlyphCount(); + float position; + if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorPosition) + { + const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorPosition, glyphCount - 1)); + position = glyph.bounds.x; + if (m_cursorPosition >= glyphCount) + position += glyph.bounds.width; + } + else + position = 0.f; + + Nz::Vector2f contentOrigin = GetContentOrigin(); + + m_cursorEntity->GetComponent().SetPosition(contentOrigin.x + position, contentOrigin.y + lineInfo.bounds.y); + } } diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 78b250aaf..3ed1a25d0 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp @@ -60,29 +60,51 @@ namespace Ndk const EntityHandle& World::CreateEntity() { EntityId id; + EntityBlock* entBlock; if (!m_freeIdList.empty()) { // We get an identifier id = m_freeIdList.back(); m_freeIdList.pop_back(); + + entBlock = &m_entities[id]; + entBlock->handle.Reset(&entBlock->entity); //< Reset handle (as it was reset when entity got destroyed) + + m_entityBlocks[id] = entBlock; } else { // We allocate a new entity - id = static_cast(m_entities.size()); + id = static_cast(m_entityBlocks.size()); - // We can't use emplace_back due to the scope - m_entities.push_back(Entity(this, id)); + if (m_entities.capacity() > m_entities.size()) + { + NazaraAssert(m_waitingEntities.empty(), "There should be no waiting entities if space is available in main container"); + + m_entities.push_back(Entity(this, id)); //< We can't use emplace_back due to the scope + entBlock = &m_entities.back(); + } + else + { + // Pushing to entities would reallocate vector and thus, invalidate EntityHandles (which we don't want until world update) + // To prevent this, allocate them into a separate vector and move them at update + // For now, we are counting on m_entities grow strategy to keep allocation frequency low + m_waitingEntities.emplace_back(std::make_unique(Entity(this, id))); + entBlock = m_waitingEntities.back().get(); + } + + if (id >= m_entityBlocks.size()) + m_entityBlocks.resize(id + 1); + + m_entityBlocks[id] = entBlock; } - // We initialise the entity and we add it to the list of alive entities - Entity& entity = m_entities[id].entity; - entity.Create(); + // We initialize the entity and we add it to the list of alive entities + entBlock->entity.Create(); - m_aliveEntities.emplace_back(&entity); - m_entities[id].aliveIndex = m_aliveEntities.size() - 1; + m_aliveEntities.Insert(&entBlock->entity); - return m_aliveEntities.back(); + return entBlock->handle; } /*! @@ -96,8 +118,10 @@ namespace Ndk // First, destruction of entities, then handles // This is made to avoid that handle warn uselessly entities before their destruction m_entities.clear(); + m_entityBlocks.clear(); + m_waitingEntities.clear(); - m_aliveEntities.clear(); + m_aliveEntities.Clear(); m_dirtyEntities.Clear(); m_killedEntities.Clear(); } @@ -120,7 +144,7 @@ namespace Ndk return EntityHandle::InvalidHandle; } - EntityHandle clone = CreateEntity(); + const EntityHandle& clone = CreateEntity(); const Nz::Bitset<>& componentBits = original->GetComponentBits(); for (std::size_t i = componentBits.FindFirst(); i != componentBits.npos; i = componentBits.FindNext(i)) @@ -129,41 +153,7 @@ namespace Ndk clone->AddComponent(std::move(component)); } - return GetEntity(clone->GetId()); - } - - /*! - * \brief Kills an entity - * - * \param Pointer to the entity - * - * \remark No change is done if entity is invalid - */ - - void World::KillEntity(Entity* entity) - { - if (IsEntityValid(entity)) - m_killedEntities.UnboundedSet(entity->GetId(), true); - } - - /*! - * \brief Gets an entity - * \return A constant reference to the modified entity - * - * \param id Identifier of the entity - * - * \remark Produces a NazaraError if entity identifier is not valid - */ - - const EntityHandle& World::GetEntity(EntityId id) - { - if (IsEntityIdValid(id)) - return m_aliveEntities[m_entities[id].aliveIndex]; - else - { - NazaraError("Invalid ID"); - return EntityHandle::InvalidHandle; - } + return clone; } /*! @@ -177,45 +167,43 @@ namespace Ndk if (!m_orderedSystemsUpdated) ReorderSystems(); + // Move waiting entities to entity list + if (!m_waitingEntities.empty()) + { + constexpr std::size_t MinEntityCapacity = 10; //< We want to be able to grow maximum entity count by at least ten without going to the waiting list + + m_entities.reserve(m_entities.size() + m_waitingEntities.size() + MinEntityCapacity); + for (auto& blockPtr : m_waitingEntities) + m_entities.push_back(std::move(*blockPtr)); + + m_waitingEntities.clear(); + + // Update entity blocks pointers + for (std::size_t i = 0; i < m_entities.size(); ++i) + m_entityBlocks[i] = &m_entities[i]; + } + // Handle killed entities before last call for (std::size_t i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i)) { - EntityBlock& block = m_entities[i]; - Entity& entity = block.entity; + NazaraAssert(i < m_entityBlocks.size(), "Entity index out of range"); - NazaraAssert(entity.IsValid(), "Entity must be valid"); - - // Send back the identifier of the entity to the free queue - m_freeIdList.push_back(entity.GetId()); + Entity* entity = &m_entityBlocks[i]->entity; // Destruction of the entity (invalidation of handle by the same way) - entity.Destroy(); + entity->Destroy(); - // We take out the handle from the list of alive entities - // With the idiom swap and pop - - NazaraAssert(block.aliveIndex < m_aliveEntities.size(), "Alive index out of range"); - - if (block.aliveIndex < m_aliveEntities.size() - 1) // If it's not the last handle - { - EntityHandle& lastHandle = m_aliveEntities.back(); - EntityHandle& myHandle = m_aliveEntities[block.aliveIndex]; - - myHandle = std::move(lastHandle); - - // We don't forget to update the index associated to the entity - m_entities[myHandle->GetId()].aliveIndex = block.aliveIndex; - } - m_aliveEntities.pop_back(); + // Send back the identifier of the entity to the free queue + m_freeIdList.push_back(entity->GetId()); } m_killedEntities.Reset(); // Handle of entities which need an update from the systems for (std::size_t i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i)) { - NazaraAssert(i < m_entities.size(), "Entity index out of range"); + NazaraAssert(i < m_entityBlocks.size(), "Entity index out of range"); - Entity* entity = &m_entities[i].entity; + Entity* entity = &m_entityBlocks[i]->entity; // Check entity validity (as it could have been reported as dirty and killed during the same iteration) if (!entity->IsValid()) @@ -242,7 +230,7 @@ namespace Ndk } else { - // No, it shouldn't, remove it if it's part of the system + // No it shouldn't, remove it if it's part of the system if (partOfSystem) system->RemoveEntity(entity); } diff --git a/build/config.lua b/build/config.lua index 8ecc7c24e..12a9f8e77 100644 --- a/build/config.lua +++ b/build/config.lua @@ -1,6 +1,9 @@ -- This file contains special configurations values, such as directories to extern libraries (Qt) -- Editing this file is not required to use/compile the engine, as default values should be enough +-- Additionnal compilation options +--AdditionalCompilationOptions = "-fsanitize=address" -- Enable ASan + -- Builds Nazara extern libraries (such as lua/STB) BuildDependencies = true diff --git a/build/scripts/actions/package.lua b/build/scripts/actions/package.lua index 62d4792b3..bc86c4ba4 100644 --- a/build/scripts/actions/package.lua +++ b/build/scripts/actions/package.lua @@ -85,7 +85,7 @@ ACTION.Function = function () local exeFileExt local exeFilterFunc if (os.is("windows")) then - binFileMasks = {"**.dll"} + binFileMasks = {"**.dll", "**.pdb"} libFileMasks = {"**.lib", "**.a"} exeFileExt = ".exe" exeFilterFunc = function (filePath) return true end diff --git a/build/scripts/common.lua b/build/scripts/common.lua index e3ea13d62..ea7097e97 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -505,11 +505,47 @@ function NazaraBuild:LoadConfig() end end + local AddStringOption = function (option, name, description) + newoption({ + trigger = name, + description = description + }) + + local str = _OPTIONS[name] + if (str) then + configTable[option] = str + end + end + + AddBoolOption("BuildDependencies", "with-extlibs", "Builds the extern libraries") AddBoolOption("BuildExamples", "with-examples", "Builds the examples") AddBoolOption("ServerMode", "server", "Excludes client-only modules/tools/examples") AddBoolOption("UniteModules", "united", "Builds all the modules as one united library") + -- AdditionalCompilationOptions + do + newoption({ + trigger = "compile-options", + description = "Specify additionnal compilation options to be added to every generated project." + }) + + configTable["AdditionalCompilationOptions"] = configTable["AdditionalCompilationOptions"] or "" + if (_OPTIONS["compile-options"] ~= nil) then + configTable["AdditionalCompilationOptions"] = configTable["AdditionalCompilationOptions"] .. ";" .. _OPTIONS["compile-options"] + end + + local configs = {} + local paths = string.explode(configTable["AdditionalCompilationOptions"], ";") + for k,v in pairs(paths) do + if (#v > 0) then + table.insert(configs, v) + end + end + + configTable["AdditionalCompilationOptions"] = configs + end + -- Configurations do newoption({ @@ -792,6 +828,8 @@ function NazaraBuild:PrepareGeneric() buildoptions("-ftree-vectorize") filter({}) + + buildoptions(self.Config["AdditionalCompilationOptions"]) end function NazaraBuild:PrepareMainWorkspace() diff --git a/build/scripts/features/index_template.html b/build/scripts/features/index_template.html index 852811a4c..43bf5aea9 100644 --- a/build/scripts/features/index_template.html +++ b/build/scripts/features/index_template.html @@ -1,71 +1,71 @@ - - - - - - Avancement de Nazara - - -
- Nazara Engine - -
- - Retrouvez le moteur sur GitHub !
- Dépôt GitHub

- Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :
- OpenClassrooms, Progdupeupl ou ZesteDeSavoir -

- ... ou pourquoi ne pas venir faire un tour sur le forum dédié au moteur ? - -
- -

Fonctionnalités de Nazara

- -
Dernière mise à jour : - %DATE% -
- -

Important:

-

Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps. - C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
- Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.

- -

Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégâts).
- Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).

- -

Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
- Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.

- -
- - - - - - - - - - - %MODULELIST% - -
Sommaire
ModuleAvancement
- - %MODULEDESCRIPTION% -
- - - - - - - - - - %MODULELIST% - -
Sommaire
ModulePourcentage
-
- + + + + + + Avancement de Nazara + + +
+ Nazara Engine + +
+ + Retrouvez le moteur sur GitHub !
+ Dépôt GitHub

+ Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :
+ OpenClassrooms, Progdupeupl ou ZesteDeSavoir +

+ ... ou pourquoi ne pas venir faire un tour sur le forum dédié au moteur ? + +
+ +

Fonctionnalités de Nazara

+ +
Dernière mise à jour : + %DATE% +
+ +

Important:

+

Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps. + C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
+ Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.

+ +

Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégâts).
+ Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).

+ +

Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
+ Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.

+ +
+ + + + + + + + + + + %MODULELIST% + +
Sommaire
ModuleAvancement
+ + %MODULEDESCRIPTION% +
+ + + + + + + + + + %MODULELIST% + +
Sommaire
ModulePourcentage
+
+ \ No newline at end of file diff --git a/build/scripts/features/style.css b/build/scripts/features/style.css index 189b2a090..ff83f706c 100644 --- a/build/scripts/features/style.css +++ b/build/scripts/features/style.css @@ -1,121 +1,121 @@ -/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */ - -body -{ - font-family: sans-serif; - text-align: center; - margin: 0; - background-color: #f1f1f1; -} - -#englob { - display: block; - margin-left: auto; - margin-right: auto; - background-color: white; - width: 50%; - min-width: 765px; - padding: 0 20px; -} - -hr { - height: 0; - border: 0; - border-top: 1px solid #eee; -} - -a -{ - color: #007ACC; -} - -a:hover -{ - color: lightblue; -} - -h1 -{ - display: inline; -} - -h2 -{ - display: inline; - text-decoration: underline; -} - -h4 -{ - text-decoration: underline; -} - -p { - text-align: justify; -} - -ol -{ - list-style-type: none; -} - -table -{ - border-collapse: collapse; - text-align: center; - display: inline-block; - border: white groove; - border-radius: 10px; - box-shadow: 0px 0px 10px lightblue; -} - -th -{ - text-shadow: 2px 2px 4px black; -} - -tr -{ - border: 1px solid white; -} - -tbody tr:hover -{ - text-shadow: 0px 0px 4px white; -} - -.description -{ - margin-left: 20px; -} - -.lastupdate -{ - font-size: x-large; - font-weight: bold; - color: #f1c40f; -} - -.modulename -{ - font-size: x-large; - font-weight: bold; - text-shadow: 2px 2px 10px #007ACC; -} - -.note -{ - margin-left: 20px; - color: #007ACC; -} - -.notedesc -{ - color: rgb(200, 200, 255); -} - -.portability -{ - margin-left: 20px; - color: red; +/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */ + +body +{ + font-family: sans-serif; + text-align: center; + margin: 0; + background-color: #f1f1f1; +} + +#englob { + display: block; + margin-left: auto; + margin-right: auto; + background-color: white; + width: 50%; + min-width: 765px; + padding: 0 20px; +} + +hr { + height: 0; + border: 0; + border-top: 1px solid #eee; +} + +a +{ + color: #007ACC; +} + +a:hover +{ + color: lightblue; +} + +h1 +{ + display: inline; +} + +h2 +{ + display: inline; + text-decoration: underline; +} + +h4 +{ + text-decoration: underline; +} + +p { + text-align: justify; +} + +ol +{ + list-style-type: none; +} + +table +{ + border-collapse: collapse; + text-align: center; + display: inline-block; + border: white groove; + border-radius: 10px; + box-shadow: 0px 0px 10px lightblue; +} + +th +{ + text-shadow: 2px 2px 4px black; +} + +tr +{ + border: 1px solid white; +} + +tbody tr:hover +{ + text-shadow: 0px 0px 4px white; +} + +.description +{ + margin-left: 20px; +} + +.lastupdate +{ + font-size: x-large; + font-weight: bold; + color: #f1c40f; +} + +.modulename +{ + font-size: x-large; + font-weight: bold; + text-shadow: 2px 2px 10px #007ACC; +} + +.note +{ + margin-left: 20px; + color: #007ACC; +} + +.notedesc +{ + color: rgb(200, 200, 255); +} + +.portability +{ + margin-left: 20px; + color: red; } \ No newline at end of file diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 863d3edea..4acbdf5a1 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -16,6 +16,7 @@ #include // Module de scripting #include // Module graphique #include // Module de rendu +#include // Module utilitaire #include // Module utilitaire #include #include @@ -33,6 +34,7 @@ int main() { // Ndk::Application est une classe s'occupant de l'initialisation du moteur ainsi que de la gestion de beaucoup de choses Ndk::Application application; + Nz::Initializer network; // 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. @@ -251,7 +253,7 @@ int main() } // On fait disparaître le curseur de la souris - window.SetCursor(Nz::WindowCursor_None); + window.SetCursor(Nz::SystemCursor_None); // On lie la caméra à la fenêtre cameraComp.SetTarget(&window); diff --git a/examples/Particles/SpacebattleDemo.cpp b/examples/Particles/SpacebattleDemo.cpp index 8cc1558c6..7f2cd6b4c 100644 --- a/examples/Particles/SpacebattleDemo.cpp +++ b/examples/Particles/SpacebattleDemo.cpp @@ -644,7 +644,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm) m_turretReloadSound.LoadFromFile("resources/turretReload.wav"); //m_onMouseMoved.Connect(m_shared.target->GetEventHandler().OnMouseMoved, this, &SpacebattleExample::OnMouseMoved); - //m_shared.target->SetCursor(Nz::WindowCursor_None); + //m_shared.target->SetCursor(Nz::SystemCursor_None); ////////////////////////////////////////////////////////////////////////// diff --git a/examples/Particles/main.cpp b/examples/Particles/main.cpp index 67bf99754..bf230bfe7 100644 --- a/examples/Particles/main.cpp +++ b/examples/Particles/main.cpp @@ -17,8 +17,6 @@ int main() { - Nz::ContextParameters::defaultCompatibilityProfile = true; - Ndk::Application app; // Mix all sounds in mono (in order to give them 3D position) diff --git a/examples/Tut00/main.cpp b/examples/Tut00/main.cpp index a1029eb99..ef894f274 100644 --- a/examples/Tut00/main.cpp +++ b/examples/Tut00/main.cpp @@ -18,6 +18,9 @@ int main(int argc, char* argv[]) Ndk::Application application(argc, argv); // Do what you want here + Nz::LuaInstance lua; + std::cout << lua.Execute("return {key = 42}") << std::endl; + std::cout << lua.DumpStack() << std::endl; return EXIT_SUCCESS; } diff --git a/examples/Tut01/main.cpp b/examples/Tut01/main.cpp index b5e07074d..b1d962e1e 100644 --- a/examples/Tut01/main.cpp +++ b/examples/Tut01/main.cpp @@ -1,4 +1,4 @@ -// Sources pour https://github.com/DigitalPulseSoftware/NazaraEngine/wiki/(FR)-Tutoriel-01---Hello-World +// Sources pour https://github.com/DigitalPulseSoftware/NazaraEngine/wiki/(FR)-Tutoriel:-%5B01%5D-Hello-World #include #include diff --git a/examples/Tut02/build.lua b/examples/Tut02/build.lua new file mode 100644 index 000000000..dbb8a8c9f --- /dev/null +++ b/examples/Tut02/build.lua @@ -0,0 +1,11 @@ +EXAMPLE.Name = "Tut02_Events" + +EXAMPLE.EnableConsole = true + +EXAMPLE.Files = { + "main.cpp" +} + +EXAMPLE.Libraries = { + "NazaraSDK" +} diff --git a/examples/Tut02/main.cpp b/examples/Tut02/main.cpp new file mode 100644 index 000000000..83de624c6 --- /dev/null +++ b/examples/Tut02/main.cpp @@ -0,0 +1,50 @@ +// Sources pour https://github.com/DigitalPulseSoftware/NazaraEngine/wiki/(FR)-Tutoriel:-%5B02%5D-Gestion-des-événements + +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) +{ + Ndk::Application application(argc, argv); + + Nz::RenderWindow& mainWindow = application.AddWindow(); + mainWindow.Create(Nz::VideoMode(800, 600, 32), "Test"); + + mainWindow.EnableCloseOnQuit(false); + + Ndk::World& world = application.AddWorld(); + world.GetSystem().SetGlobalUp(Nz::Vector3f::Down()); + world.GetSystem().SetDefaultBackground(Nz::ColorBackground::New(Nz::Color(117, 122, 214))); + + Ndk::EntityHandle viewEntity = world.CreateEntity(); + viewEntity->AddComponent(); + + Ndk::CameraComponent& viewer = viewEntity->AddComponent(); + viewer.SetTarget(&mainWindow); + viewer.SetProjectionType(Nz::ProjectionType_Orthogonal); + + + Nz::EventHandler& eventHandler = mainWindow.GetEventHandler(); + eventHandler.OnKeyPressed.Connect([](const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& e) + { + std::cout << Nz::Keyboard::GetKeyName(e.code) << std::endl; + + // Profitons-en aussi pour nous donner un moyen de quitter le programme + if (e.code == Nz::Keyboard::Escape) + Ndk::Application::Instance()->Quit(); // Cette ligne casse la boucle Run() de l'application + }); + + + while (application.Run()) + { + mainWindow.Display(); + } + + return EXIT_SUCCESS; +} diff --git a/include/Nazara/Audio/Algorithm.hpp b/include/Nazara/Audio/Algorithm.hpp index ea5bd09b6..5173cbdb2 100644 --- a/include/Nazara/Audio/Algorithm.hpp +++ b/include/Nazara/Audio/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Algorithm.inl b/include/Nazara/Audio/Algorithm.inl index ce3c87369..64f0b9f46 100644 --- a/include/Nazara/Audio/Algorithm.inl +++ b/include/Nazara/Audio/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Audio.hpp b/include/Nazara/Audio/Audio.hpp index c80d478d0..1a7c7a1a4 100644 --- a/include/Nazara/Audio/Audio.hpp +++ b/include/Nazara/Audio/Audio.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/ConfigCheck.hpp b/include/Nazara/Audio/ConfigCheck.hpp index 70d0c6fe5..e69257bd5 100644 --- a/include/Nazara/Audio/ConfigCheck.hpp +++ b/include/Nazara/Audio/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Debug.hpp b/include/Nazara/Audio/Debug.hpp index 4e6124741..4ff3e269a 100644 --- a/include/Nazara/Audio/Debug.hpp +++ b/include/Nazara/Audio/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/DebugOff.hpp b/include/Nazara/Audio/DebugOff.hpp index e5149d5b5..557486b46 100644 --- a/include/Nazara/Audio/DebugOff.hpp +++ b/include/Nazara/Audio/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Enums.hpp b/include/Nazara/Audio/Enums.hpp index 20866e5e9..80c4dd91f 100644 --- a/include/Nazara/Audio/Enums.hpp +++ b/include/Nazara/Audio/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 29e71fab7..86ccc6906 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -43,27 +43,27 @@ namespace Nz bool Create(SoundStream* soundStream); void Destroy(); - void EnableLooping(bool loop); + void EnableLooping(bool loop) override; - UInt32 GetDuration() const; + UInt32 GetDuration() const override; AudioFormat GetFormat() const; - UInt32 GetPlayingOffset() const; + UInt32 GetPlayingOffset() const override; UInt64 GetSampleCount() const; UInt32 GetSampleRate() const; - SoundStatus GetStatus() const; + SoundStatus GetStatus() const override; - bool IsLooping() const; + bool IsLooping() const override; bool OpenFromFile(const String& filePath, const MusicParams& params = MusicParams()); bool OpenFromMemory(const void* data, std::size_t size, const MusicParams& params = MusicParams()); bool OpenFromStream(Stream& stream, const MusicParams& params = MusicParams()); - void Pause(); - void Play(); + void Pause() override; + void Play() override; void SetPlayingOffset(UInt32 offset); - void Stop(); + void Stop() override; Music& operator=(const Music&) = delete; Music& operator=(Music&&) = delete; ///TODO diff --git a/include/Nazara/Audio/OpenAL.hpp b/include/Nazara/Audio/OpenAL.hpp index aa80f406e..79345c907 100644 --- a/include/Nazara/Audio/OpenAL.hpp +++ b/include/Nazara/Audio/OpenAL.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index 23d6f11bd..114b177ab 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -23,14 +23,14 @@ namespace Nz Sound(Sound&&) = default; ~Sound(); - void EnableLooping(bool loop); + void EnableLooping(bool loop) override; const SoundBuffer* GetBuffer() const; - UInt32 GetDuration() const; - UInt32 GetPlayingOffset() const; - SoundStatus GetStatus() const; + UInt32 GetDuration() const override; + UInt32 GetPlayingOffset() const override; + SoundStatus GetStatus() const override; - bool IsLooping() const; + bool IsLooping() const override; bool IsPlayable() const; bool IsPlaying() const; @@ -38,13 +38,13 @@ namespace Nz bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); bool LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams()); - void Pause(); - void Play(); + void Pause() override; + void Play() override; void SetBuffer(const SoundBuffer* buffer); void SetPlayingOffset(UInt32 offset); - void Stop(); + void Stop() override; Sound& operator=(const Sound&) = delete; ///TODO? Sound& operator=(Sound&&) = default; diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 6b8e5c385..db38f780f 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/SoundBuffer.inl b/include/Nazara/Audio/SoundBuffer.inl index a4c42be69..bb4168d2c 100644 --- a/include/Nazara/Audio/SoundBuffer.inl +++ b/include/Nazara/Audio/SoundBuffer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index 9a68d88cc..4bcdca176 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/SoundStream.hpp b/include/Nazara/Audio/SoundStream.hpp index 8fd93f412..1d821272b 100644 --- a/include/Nazara/Audio/SoundStream.hpp +++ b/include/Nazara/Audio/SoundStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 419ddaae9..606d6969a 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index f3c848ed3..92da667bd 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/AbstractLogger.hpp b/include/Nazara/Core/AbstractLogger.hpp index fbe61c080..fb2ba6c0f 100644 --- a/include/Nazara/Core/AbstractLogger.hpp +++ b/include/Nazara/Core/AbstractLogger.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index a6d5e77a7..ceba7f14e 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index fea1fd964..a1d846085 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index 622238854..04fb2f3c6 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -145,7 +145,7 @@ namespace Nz template void* operator&() const; - operator bool() const; + explicit operator bool() const; Bit& operator=(bool val); Bit& operator=(const Bit& bit); diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index afec6983a..44a5e2c16 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ByteArray.hpp b/include/Nazara/Core/ByteArray.hpp index 4bdc34150..d6a4a6f27 100644 --- a/include/Nazara/Core/ByteArray.hpp +++ b/include/Nazara/Core/ByteArray.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index b5d8b1510..81406d84f 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp index fab7c8f4a..eed461205 100644 --- a/include/Nazara/Core/ByteStream.hpp +++ b/include/Nazara/Core/ByteStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -24,7 +24,7 @@ namespace Nz ByteStream(const void* ptr, Nz::UInt64 size); ByteStream(const ByteStream&) = delete; inline ByteStream(ByteStream&& stream); - ~ByteStream(); + virtual ~ByteStream(); inline Endianness GetDataEndianness() const; inline Nz::UInt64 GetSize() const; diff --git a/include/Nazara/Core/ByteStream.inl b/include/Nazara/Core/ByteStream.inl index dadc056ca..1dbf9535e 100644 --- a/include/Nazara/Core/ByteStream.inl +++ b/include/Nazara/Core/ByteStream.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/CallOnExit.hpp b/include/Nazara/Core/CallOnExit.hpp index 3c11ea205..dd0d60728 100644 --- a/include/Nazara/Core/CallOnExit.hpp +++ b/include/Nazara/Core/CallOnExit.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/CallOnExit.inl b/include/Nazara/Core/CallOnExit.inl index 0318752cc..d4c5e393c 100644 --- a/include/Nazara/Core/CallOnExit.inl +++ b/include/Nazara/Core/CallOnExit.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Clock.hpp b/include/Nazara/Core/Clock.hpp index e624c59d8..870d88c9f 100644 --- a/include/Nazara/Core/Clock.hpp +++ b/include/Nazara/Core/Clock.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 5fef4f854..4ed06796f 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 5d71393df..6d9fe4d35 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index 19ab9e863..d73cb0f8f 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ConditionVariable.inl b/include/Nazara/Core/ConditionVariable.inl index 636c98493..f9603e1c1 100644 --- a/include/Nazara/Core/ConditionVariable.inl +++ b/include/Nazara/Core/ConditionVariable.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Config.hpp b/include/Nazara/Core/Config.hpp index 2ad2513ac..5aa9fccec 100644 --- a/include/Nazara/Core/Config.hpp +++ b/include/Nazara/Core/Config.hpp @@ -73,7 +73,7 @@ #define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096 // Optimize the Windows implementation with technologies of Windows NT 6.0 (and greater) (Break the compatibility with Windows XP) -#define NAZARA_CORE_WINDOWS_NT6 0 +#define NAZARA_CORE_WINDOWS_NT6 1 /* diff --git a/include/Nazara/Core/ConfigCheck.hpp b/include/Nazara/Core/ConfigCheck.hpp index aa1ac5cfa..0e3b1e66e 100644 --- a/include/Nazara/Core/ConfigCheck.hpp +++ b/include/Nazara/Core/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Core.hpp b/include/Nazara/Core/Core.hpp index 00840dc1a..672e4ecc9 100644 --- a/include/Nazara/Core/Core.hpp +++ b/include/Nazara/Core/Core.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Debug.hpp b/include/Nazara/Core/Debug.hpp index 6301f574a..3a3d0444c 100644 --- a/include/Nazara/Core/Debug.hpp +++ b/include/Nazara/Core/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Debug/NewRedefinition.hpp b/include/Nazara/Core/Debug/NewRedefinition.hpp index 5b9b2088f..b50d4feb3 100644 --- a/include/Nazara/Core/Debug/NewRedefinition.hpp +++ b/include/Nazara/Core/Debug/NewRedefinition.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/DebugOff.hpp b/include/Nazara/Core/DebugOff.hpp index 62788ee15..931fa629d 100644 --- a/include/Nazara/Core/DebugOff.hpp +++ b/include/Nazara/Core/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index 9dd24ee7d..21a1da8da 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index 4f2759e22..2f4ccb530 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp index 8bd1d61b4..5ebd558e2 100644 --- a/include/Nazara/Core/Endianness.hpp +++ b/include/Nazara/Core/Endianness.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index 67df87c45..3ef527105 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 1020cd2b6..2bacb1f2d 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -105,7 +105,7 @@ namespace Nz { ParameterType_Boolean, ParameterType_Color, - ParameterType_Float, + ParameterType_Double, ParameterType_Integer, ParameterType_None, ParameterType_Pointer, diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index fbc4de38b..cd9e49fe6 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp index 43f2ae589..76d89a858 100644 --- a/include/Nazara/Core/ErrorFlags.hpp +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index d4d1e6522..86a224314 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/File.inl b/include/Nazara/Core/File.inl index ff0d148fd..15ac3fabd 100644 --- a/include/Nazara/Core/File.inl +++ b/include/Nazara/Core/File.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/FileLogger.hpp b/include/Nazara/Core/FileLogger.hpp index d7b1d8f14..7ca79f66c 100644 --- a/include/Nazara/Core/FileLogger.hpp +++ b/include/Nazara/Core/FileLogger.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Flags.hpp b/include/Nazara/Core/Flags.hpp index d4f536356..b7dff544b 100644 --- a/include/Nazara/Core/Flags.hpp +++ b/include/Nazara/Core/Flags.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -29,7 +29,7 @@ namespace Nz public: using BitField = typename std::conditional<(EnumAsFlags::max > 32), UInt64, UInt32>::type; - constexpr Flags(BitField value); + constexpr Flags(BitField value = 0); constexpr Flags(E enumVal); explicit constexpr operator bool() const; @@ -55,12 +55,20 @@ namespace Nz BitField m_value; }; - template constexpr std::enable_if_t::value, Flags> operator~(E lhs); - template constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs); - template constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs); - template constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs); + // Little hack to have them in both Nz and global scope + namespace FlagsOperators + { + template constexpr std::enable_if_t::value, Flags> operator~(E lhs); + template constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs); + template constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs); + } + + using namespace FlagsOperators; } +using namespace Nz::FlagsOperators; + #include #endif // NAZARA_FLAGS_HPP diff --git a/include/Nazara/Core/Flags.inl b/include/Nazara/Core/Flags.inl index 26e82c56c..1899e7576 100644 --- a/include/Nazara/Core/Flags.inl +++ b/include/Nazara/Core/Flags.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -13,13 +13,13 @@ namespace Nz * \brief Core class used to combine enumeration values into flags bitfield */ - /*! - * \brief Constructs a Flags object using a bitfield - * - * \param value Bitfield to be used + /*! + * \brief Constructs a Flags object using a bitfield + * + * \param value Bitfield to be used * * Uses a bitfield to builds the flag value. (e.g. if bit 0 is active, then Enum value 0 will be set as active). - */ + */ template constexpr Flags::Flags(BitField value) : m_value(value) @@ -211,65 +211,68 @@ namespace Nz } - /*! - * \brief Override binary NOT operator on enum to turns into a Flags object. - * \return A Flags object with reversed bits. - * - * \param lhs Enumeration value to reverse. - * - * Returns a Flags object with all state enabled except for the enum one. - */ - template - constexpr std::enable_if_t::value, Flags> operator~(E lhs) + namespace FlagsOperators { - return ~Flags(lhs); - } + /*! + * \brief Override binary NOT operator on enum to turns into a Flags object. + * \return A Flags object with reversed bits. + * + * \param lhs Enumeration value to reverse. + * + * Returns a Flags object with all state enabled except for the enum one. + */ + template + constexpr std::enable_if_t::value, Flags> operator~(E lhs) + { + return ~Flags(lhs); + } - /*! - * \brief Override binary OR operator on enum to turns into a Flags object. - * \return A Flags object with combined enum states. - * - * \param lhs First enumeration value to combine. - * \param rhs Second enumeration value to combine. - * - * Returns a Flags object with combined states from the two enumeration values. - */ - template - constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs) - { - return Flags(lhs) | rhs; - } + /*! + * \brief Override binary OR operator on enum to turns into a Flags object. + * \return A Flags object with combined enum states. + * + * \param lhs First enumeration value to combine. + * \param rhs Second enumeration value to combine. + * + * Returns a Flags object with combined states from the two enumeration values. + */ + template + constexpr std::enable_if_t::value, Flags> operator|(E lhs, E rhs) + { + return Flags(lhs) | rhs; + } - /*! - * \brief Override binary AND operator on enum to turns into a Flags object. - * \return A Flags object with compare enum states. - * - * \param lhs First enumeration value to compare. - * \param rhs Second enumeration value to compare. - * - * Returns a Flags object with compared states from the two enumeration values. - * In this case, only one flag will be enabled if both enumeration values are the same. - */ - template - constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs) - { - return Flags(lhs) & rhs; - } + /*! + * \brief Override binary AND operator on enum to turns into a Flags object. + * \return A Flags object with compare enum states. + * + * \param lhs First enumeration value to compare. + * \param rhs Second enumeration value to compare. + * + * Returns a Flags object with compared states from the two enumeration values. + * In this case, only one flag will be enabled if both enumeration values are the same. + */ + template + constexpr std::enable_if_t::value, Flags> operator&(E lhs, E rhs) + { + return Flags(lhs) & rhs; + } - /*! - * \brief Override binary XOR operator on enum to turns into a Flags object. - * \return A Flags object with XORed enum states. - * - * \param lhs First enumeration value to compare. - * \param rhs Second enumeration value to compare. - * - * Returns a Flags object with XORed states from the two enumeration values. - * In this case, two flags will be enabled if both the enumeration values are different. - */ - template - constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs) - { - return Flags(lhs) ^ rhs; + /*! + * \brief Override binary XOR operator on enum to turns into a Flags object. + * \return A Flags object with XORed enum states. + * + * \param lhs First enumeration value to compare. + * \param rhs Second enumeration value to compare. + * + * Returns a Flags object with XORed states from the two enumeration values. + * In this case, two flags will be enabled if both the enumeration values are different. + */ + template + constexpr std::enable_if_t::value, Flags> operator^(E lhs, E rhs) + { + return Flags(lhs) ^ rhs; + } } } diff --git a/include/Nazara/Core/Functor.hpp b/include/Nazara/Core/Functor.hpp index 7ce9995a7..17578474c 100644 --- a/include/Nazara/Core/Functor.hpp +++ b/include/Nazara/Core/Functor.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -25,7 +25,7 @@ namespace Nz { FunctorWithoutArgs(F func); - void Run(); + void Run() override; private: F m_func; @@ -36,7 +36,7 @@ namespace Nz { FunctorWithArgs(F func, Args&&... args); - void Run(); + void Run() override; private: F m_func; @@ -48,7 +48,7 @@ namespace Nz { MemberWithoutArgs(void (C::*func)(), C* object); - void Run(); + void Run() override; private: void (C::*m_func)(); diff --git a/include/Nazara/Core/Functor.inl b/include/Nazara/Core/Functor.inl index d5cefe434..ea7bdbad2 100644 --- a/include/Nazara/Core/Functor.inl +++ b/include/Nazara/Core/Functor.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/GuillotineBinPack.hpp b/include/Nazara/Core/GuillotineBinPack.hpp index 878df27ea..61671ff50 100644 --- a/include/Nazara/Core/GuillotineBinPack.hpp +++ b/include/Nazara/Core/GuillotineBinPack.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/HandledObject.hpp b/include/Nazara/Core/HandledObject.hpp index eeb9c4bfa..a103f6750 100644 --- a/include/Nazara/Core/HandledObject.hpp +++ b/include/Nazara/Core/HandledObject.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/include/Nazara/Core/HandledObject.inl b/include/Nazara/Core/HandledObject.inl index 43feebcd3..53f77bbed 100644 --- a/include/Nazara/Core/HandledObject.inl +++ b/include/Nazara/Core/HandledObject.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/include/Nazara/Core/HardwareInfo.hpp b/include/Nazara/Core/HardwareInfo.hpp index 2a79165cf..73b49e894 100644 --- a/include/Nazara/Core/HardwareInfo.hpp +++ b/include/Nazara/Core/HardwareInfo.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Hash/CRC32.hpp b/include/Nazara/Core/Hash/CRC32.hpp index 79da031b3..444b81ae5 100644 --- a/include/Nazara/Core/Hash/CRC32.hpp +++ b/include/Nazara/Core/Hash/CRC32.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Hash/Fletcher16.hpp b/include/Nazara/Core/Hash/Fletcher16.hpp index 6bc95db68..a360c3adf 100644 --- a/include/Nazara/Core/Hash/Fletcher16.hpp +++ b/include/Nazara/Core/Hash/Fletcher16.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/MD5.hpp b/include/Nazara/Core/Hash/MD5.hpp index 1c8bd0d25..28026816b 100644 --- a/include/Nazara/Core/Hash/MD5.hpp +++ b/include/Nazara/Core/Hash/MD5.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA1.hpp b/include/Nazara/Core/Hash/SHA1.hpp index 8e410adb7..55291e1f7 100644 --- a/include/Nazara/Core/Hash/SHA1.hpp +++ b/include/Nazara/Core/Hash/SHA1.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA224.hpp b/include/Nazara/Core/Hash/SHA224.hpp index 48893c8d0..3013a8170 100644 --- a/include/Nazara/Core/Hash/SHA224.hpp +++ b/include/Nazara/Core/Hash/SHA224.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA256.hpp b/include/Nazara/Core/Hash/SHA256.hpp index 1adf5ad52..e20e1d994 100644 --- a/include/Nazara/Core/Hash/SHA256.hpp +++ b/include/Nazara/Core/Hash/SHA256.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA384.hpp b/include/Nazara/Core/Hash/SHA384.hpp index 54643cbbd..814d80f57 100644 --- a/include/Nazara/Core/Hash/SHA384.hpp +++ b/include/Nazara/Core/Hash/SHA384.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA512.hpp b/include/Nazara/Core/Hash/SHA512.hpp index a17726b74..df09cd163 100644 --- a/include/Nazara/Core/Hash/SHA512.hpp +++ b/include/Nazara/Core/Hash/SHA512.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/Whirlpool.hpp b/include/Nazara/Core/Hash/Whirlpool.hpp index f7922254d..caff8f349 100644 --- a/include/Nazara/Core/Hash/Whirlpool.hpp +++ b/include/Nazara/Core/Hash/Whirlpool.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Initializer.hpp b/include/Nazara/Core/Initializer.hpp index d884dfcc8..c09ae55af 100644 --- a/include/Nazara/Core/Initializer.hpp +++ b/include/Nazara/Core/Initializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -24,7 +24,7 @@ namespace Nz bool IsInitialized() const; void Uninitialize(); - operator bool() const; + explicit operator bool() const; Initializer& operator=(const Initializer&) = delete; Initializer& operator=(Initializer&&) = delete; ///TODO diff --git a/include/Nazara/Core/Initializer.inl b/include/Nazara/Core/Initializer.inl index 23cc7b2de..0d886d0a0 100644 --- a/include/Nazara/Core/Initializer.inl +++ b/include/Nazara/Core/Initializer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/LockGuard.hpp b/include/Nazara/Core/LockGuard.hpp index d9ef5aa85..d8d03725c 100644 --- a/include/Nazara/Core/LockGuard.hpp +++ b/include/Nazara/Core/LockGuard.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/LockGuard.inl b/include/Nazara/Core/LockGuard.inl index 73beab112..4fa95884f 100644 --- a/include/Nazara/Core/LockGuard.inl +++ b/include/Nazara/Core/LockGuard.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index fc64c8a49..f3826f568 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/MemoryHelper.hpp b/include/Nazara/Core/MemoryHelper.hpp index e2ed7fc3e..dc1bcc475 100644 --- a/include/Nazara/Core/MemoryHelper.hpp +++ b/include/Nazara/Core/MemoryHelper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -38,6 +38,9 @@ namespace Nz template T* PlacementNew(T* ptr, Args&&... args); + template + void PlacementDestroy(T* ptr); + class StackAllocation { public: diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index d3fe43155..dcee8ca4e 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -64,6 +64,17 @@ namespace Nz return new (ptr) T(std::forward(args)...); } + /*! + * \brief Calls the object destructor explicitly + * + * \param ptr Pointer to a previously constructed pointer on raw memory + */ + template + void PlacementDestroy(T* ptr) + { + ptr->~T(); + } + /*! * \ingroup core * \class Nz::StackAllocation diff --git a/include/Nazara/Core/MemoryManager.hpp b/include/Nazara/Core/MemoryManager.hpp index 39d5be712..caed09b61 100644 --- a/include/Nazara/Core/MemoryManager.hpp +++ b/include/Nazara/Core/MemoryManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/MemoryPool.hpp b/include/Nazara/Core/MemoryPool.hpp index 7aaa462bb..10f147f5c 100644 --- a/include/Nazara/Core/MemoryPool.hpp +++ b/include/Nazara/Core/MemoryPool.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -22,12 +22,14 @@ namespace Nz ~MemoryPool() = default; void* Allocate(unsigned int size); + template void Delete(T* ptr); + void Free(void* ptr); - unsigned int GetBlockSize() const; - unsigned int GetFreeBlocks() const; - unsigned int GetSize() const; + inline unsigned int GetBlockSize() const; + inline unsigned int GetFreeBlocks() const; + inline unsigned int GetSize() const; template T* New(Args&&... args); diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 732c50fa9..41443e38b 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -1,7 +1,8 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -95,9 +96,8 @@ namespace Nz * * \remark If ptr is null, nothing is done */ - template - inline void MemoryPool::Delete(T* ptr) + void MemoryPool::Delete(T* ptr) { if (ptr) { diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 929e8e5bd..4c34eabc6 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) 2017 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 diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl index 6cdf06b26..e1369d819 100644 --- a/include/Nazara/Core/MemoryStream.inl +++ b/include/Nazara/Core/MemoryStream.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/MemoryView.hpp b/include/Nazara/Core/MemoryView.hpp index 41f4b1ee2..5b3cf63b7 100644 --- a/include/Nazara/Core/MemoryView.hpp +++ b/include/Nazara/Core/MemoryView.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index 14de9d282..303b163f1 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Mutex.inl b/include/Nazara/Core/Mutex.inl index fe4a77577..9e79fff02 100644 --- a/include/Nazara/Core/Mutex.inl +++ b/include/Nazara/Core/Mutex.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ObjectHandle.hpp b/include/Nazara/Core/ObjectHandle.hpp index b3cc080dd..022344488 100644 --- a/include/Nazara/Core/ObjectHandle.hpp +++ b/include/Nazara/Core/ObjectHandle.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -38,7 +38,7 @@ namespace Nz Nz::String ToString() const; - operator bool() const; + explicit operator bool() const; operator T*() const; T* operator->() const; @@ -69,7 +69,7 @@ namespace Nz 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 ObjectHandle&, const ObjectHandle& rhs); template bool operator<=(const T& lhs, const ObjectHandle& rhs); template bool operator<=(const ObjectHandle& lhs, const T& rhs); diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl index d5badc964..f4c70ae85 100644 --- a/include/Nazara/Core/ObjectHandle.inl +++ b/include/Nazara/Core/ObjectHandle.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -128,6 +128,9 @@ namespace Nz template void ObjectHandle::Reset(ObjectHandle&& handle) noexcept { + if (this == &handle) + return; + if (m_object) m_object->UnregisterHandle(this); diff --git a/include/Nazara/Core/ObjectLibrary.hpp b/include/Nazara/Core/ObjectLibrary.hpp index ee0a40e29..a13fbc3e6 100644 --- a/include/Nazara/Core/ObjectLibrary.hpp +++ b/include/Nazara/Core/ObjectLibrary.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ObjectLibrary.inl b/include/Nazara/Core/ObjectLibrary.inl index e656a820e..b5384a2a7 100644 --- a/include/Nazara/Core/ObjectLibrary.inl +++ b/include/Nazara/Core/ObjectLibrary.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 6a69a22ee..3a9e57628 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -31,7 +31,7 @@ namespace Nz bool Reset(T* object = nullptr); ObjectRef& Swap(ObjectRef& ref); - operator bool() const; + explicit operator bool() const; operator T*() const; T* operator->() const; diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index 85baff8bf..c3e783186 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index d6596dcf2..5c26aa870 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index b34f0eca0..d6b3985b4 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -27,10 +27,13 @@ namespace Nz void Clear(); + inline void ForEach(const std::function& callback); + inline void ForEach(const std::function& callback) const; + bool GetBooleanParameter(const String& name, bool* value) const; bool GetColorParameter(const String& name, Color* value) const; - bool GetFloatParameter(const String& name, float* value) const; - bool GetIntegerParameter(const String& name, int* value) const; + bool GetDoubleParameter(const String& name, double* value) const; + bool GetIntegerParameter(const String& name, long long* value) const; bool GetParameterType(const String& name, ParameterType* type) const; bool GetPointerParameter(const String& name, void** value) const; bool GetStringParameter(const String& name, String* value) const; @@ -45,8 +48,8 @@ namespace Nz void SetParameter(const String& name, const String& value); void SetParameter(const String& name, const char* value); void SetParameter(const String& name, bool value); - void SetParameter(const String& name, float value); - void SetParameter(const String& name, int value); + void SetParameter(const String& name, double value); + void SetParameter(const String& name, long long value); void SetParameter(const String& name, void* value); void SetParameter(const String& name, void* value, Destructor destructor); @@ -81,8 +84,8 @@ namespace Nz ~Value() {} bool boolVal; - float floatVal; - int intVal; + double doubleVal; + long long intVal; void* ptrVal; Color colorVal; String stringVal; @@ -102,4 +105,6 @@ namespace Nz std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList); +#include + #endif // NAZARA_PARAMETERLIST_HPP diff --git a/include/Nazara/Core/ParameterList.inl b/include/Nazara/Core/ParameterList.inl new file mode 100644 index 000000000..b1983b49b --- /dev/null +++ b/include/Nazara/Core/ParameterList.inl @@ -0,0 +1,42 @@ +// Copyright (C) 2017 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 +{ + /*! + * \brief Iterates over every value of the parameter list + * + * \param callback Callback function called with every parameter contained in the list, which can return true to remove the key (or false to keep it) + * + * \remark Changing the ParameterList while iterating on it may cause bugs, but querying data is safe. + */ + inline void ParameterList::ForEach(const std::function& callback) + { + for (auto it = m_parameters.begin(); it != m_parameters.end();) + { + if (callback(*this, it->first)) + it = m_parameters.erase(it); + else + ++it; + } + } + + /*! + * \brief Iterates over every value of the parameter list + * + * \param callback Callback function called with every parameter contained in the list + * + * \remark Changing the ParameterList while iterating on it may cause bugs, but querying data is safe. + */ + inline void ParameterList::ForEach(const std::function& callback) const + { + for (auto& pair : m_parameters) + callback(*this, pair.first); + } +} + +#include diff --git a/include/Nazara/Core/PluginManager.hpp b/include/Nazara/Core/PluginManager.hpp index 833f0c5d2..5857a2255 100644 --- a/include/Nazara/Core/PluginManager.hpp +++ b/include/Nazara/Core/PluginManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Primitive.hpp b/include/Nazara/Core/Primitive.hpp index 16c27100d..7afcace47 100644 --- a/include/Nazara/Core/Primitive.hpp +++ b/include/Nazara/Core/Primitive.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index 8124a7ed9..fff7f82bb 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index 79d2363c2..a8cbed1d0 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/RefCounted.hpp b/include/Nazara/Core/RefCounted.hpp index 542784787..7a2f8c7fc 100644 --- a/include/Nazara/Core/RefCounted.hpp +++ b/include/Nazara/Core/RefCounted.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index 7d1a12530..2322b25c1 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index 8af3e3cd3..3fce094e0 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 2ac72c6df..c60be5674 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceManager.hpp b/include/Nazara/Core/ResourceManager.hpp index ca5735811..c99e84f78 100644 --- a/include/Nazara/Core/ResourceManager.hpp +++ b/include/Nazara/Core/ResourceManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceManager.inl b/include/Nazara/Core/ResourceManager.inl index 6fec2aae0..d590cc680 100644 --- a/include/Nazara/Core/ResourceManager.inl +++ b/include/Nazara/Core/ResourceManager.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceParameters.hpp b/include/Nazara/Core/ResourceParameters.hpp index e4f32e06a..8ddbecec1 100644 --- a/include/Nazara/Core/ResourceParameters.hpp +++ b/include/Nazara/Core/ResourceParameters.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceSaver.hpp b/include/Nazara/Core/ResourceSaver.hpp index 05b6d7175..08e7ae745 100644 --- a/include/Nazara/Core/ResourceSaver.hpp +++ b/include/Nazara/Core/ResourceSaver.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ResourceSaver.inl b/include/Nazara/Core/ResourceSaver.inl index a22c29d60..007f4cc75 100644 --- a/include/Nazara/Core/ResourceSaver.inl +++ b/include/Nazara/Core/ResourceSaver.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Semaphore.hpp b/include/Nazara/Core/Semaphore.hpp index c64ebc4e0..8c18cf6f4 100644 --- a/include/Nazara/Core/Semaphore.hpp +++ b/include/Nazara/Core/Semaphore.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/SerializationContext.hpp b/include/Nazara/Core/SerializationContext.hpp index 64c558a7b..cf5d83223 100644 --- a/include/Nazara/Core/SerializationContext.hpp +++ b/include/Nazara/Core/SerializationContext.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/SerializationContext.inl b/include/Nazara/Core/SerializationContext.inl index 47f56e5c2..5edd4e618 100644 --- a/include/Nazara/Core/SerializationContext.inl +++ b/include/Nazara/Core/SerializationContext.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Signal.hpp b/include/Nazara/Core/Signal.hpp index 613502f80..1569c5d0e 100644 --- a/include/Nazara/Core/Signal.hpp +++ b/include/Nazara/Core/Signal.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -33,7 +33,7 @@ namespace Nz Signal(); Signal(const Signal&) = delete; - Signal(Signal&& signal); + Signal(Signal&& signal) noexcept; ~Signal() = default; void Clear(); @@ -48,7 +48,7 @@ namespace Nz void operator()(Args... args) const; Signal& operator=(const Signal&) = delete; - Signal& operator=(Signal&& signal); + Signal& operator=(Signal&& signal) noexcept; private: struct Slot; @@ -69,7 +69,7 @@ namespace Nz SlotListIndex index; }; - void Disconnect(const SlotPtr& slot); + void Disconnect(const SlotPtr& slot) noexcept; SlotList m_slots; mutable SlotListIndex m_slotIterator; @@ -84,17 +84,17 @@ namespace Nz public: Connection() = default; Connection(const Connection& connection) = default; - Connection(Connection&& connection) = default; + Connection(Connection&& connection) noexcept; ~Connection() = default; template void Connect(BaseClass& signal, ConnectArgs&&... args); - void Disconnect(); + void Disconnect() noexcept; bool IsConnected() const; Connection& operator=(const Connection& connection) = default; - Connection& operator=(Connection&& connection) = default; + Connection& operator=(Connection&& connection) noexcept; private: Connection(const SlotPtr& slot); @@ -113,12 +113,12 @@ namespace Nz ConnectionGuard(const Connection& connection); ConnectionGuard(const ConnectionGuard& connection) = delete; ConnectionGuard(Connection&& connection); - ConnectionGuard(ConnectionGuard&& connection) = default; + ConnectionGuard(ConnectionGuard&& connection) noexcept = default; ~ConnectionGuard(); template void Connect(BaseClass& signal, ConnectArgs&&... args); - void Disconnect(); + void Disconnect() noexcept; Connection& GetConnection(); @@ -127,7 +127,7 @@ namespace Nz ConnectionGuard& operator=(const Connection& connection); ConnectionGuard& operator=(const ConnectionGuard& connection) = delete; ConnectionGuard& operator=(Connection&& connection); - ConnectionGuard& operator=(ConnectionGuard&& connection); + ConnectionGuard& operator=(ConnectionGuard&& connection) noexcept; private: Connection m_connection; diff --git a/include/Nazara/Core/Signal.inl b/include/Nazara/Core/Signal.inl index 93e0166c0..c4e89bd40 100644 --- a/include/Nazara/Core/Signal.inl +++ b/include/Nazara/Core/Signal.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -32,7 +32,7 @@ namespace Nz */ template - Signal::Signal(Signal&& signal) + Signal::Signal(Signal&& signal) noexcept { operator=(std::move(signal)); } @@ -182,7 +182,7 @@ namespace Nz */ template - Signal& Signal::operator=(Signal&& signal) + Signal& Signal::operator=(Signal&& signal) noexcept { m_slots = std::move(signal.m_slots); m_slotIterator = signal.m_slotIterator; @@ -205,7 +205,7 @@ namespace Nz */ template - void Signal::Disconnect(const SlotPtr& slot) + void Signal::Disconnect(const SlotPtr& slot) noexcept { NazaraAssert(slot, "Invalid slot pointer"); NazaraAssert(slot->index < m_slots.size(), "Invalid slot index"); @@ -246,6 +246,18 @@ namespace Nz * \brief Core class that represents a connection attached to a signal */ + /*! + * \brief Constructs a Signal::Connection object with by move semantic + * + * \param connection Connection object to move + */ + template + Signal::Connection::Connection(Connection&& connection) noexcept : + m_ptr(std::move(connection.m_ptr)) + { + connection.m_ptr.reset(); //< Fuck you GCC 4.9 + } + /*! * \brief Constructs a Signal::Connection object with a slot * @@ -277,7 +289,7 @@ namespace Nz */ template - void Signal::Connection::Disconnect() + void Signal::Connection::Disconnect() noexcept { if (SlotPtr ptr = m_ptr.lock()) ptr->signal->Disconnect(ptr); @@ -294,6 +306,20 @@ namespace Nz return !m_ptr.expired(); } + /*! + * \brief Constructs a Signal::ConnectionGuard object by move semantic + * + * \param connection Connection to move + */ + template + typename Signal::Connection& Signal::Connection::operator=(Connection&& connection) noexcept + { + m_ptr = std::move(connection.m_ptr); + connection.m_ptr.reset(); //< Fuck you GCC 4.9 + + return *this; + } + /*! * \class Nz::Signal::ConnectionGuard * \brief Core class that represents a RAII for a connection attached to a signal @@ -353,7 +379,7 @@ namespace Nz */ template - void Signal::ConnectionGuard::Disconnect() + void Signal::ConnectionGuard::Disconnect() noexcept { m_connection.Disconnect(); } @@ -406,8 +432,11 @@ namespace Nz template typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(Connection&& connection) { - m_connection.Disconnect(); - m_connection = std::move(connection); + if (&connection != this) + { + m_connection.Disconnect(); + m_connection = std::move(connection); + } return *this; } @@ -420,10 +449,13 @@ namespace Nz */ template - typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(ConnectionGuard&& connection) + typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(ConnectionGuard&& connection) noexcept { - m_connection.Disconnect(); - m_connection = std::move(connection.m_connection); + if (&connection != this) + { + m_connection.Disconnect(); + m_connection = std::move(connection.m_connection); + } return *this; } diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 6e36fcc57..10e76c9c3 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -41,7 +41,7 @@ namespace Nz void SetPtr(VoidPtr ptr); void SetStride(int stride); - operator bool() const; + explicit operator bool() const; operator T*() const; T& operator*() const; T* operator->() const; diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index 0da69b0ad..db8fb6b33 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/StdLogger.hpp b/include/Nazara/Core/StdLogger.hpp index 16fd0bb47..ecc6e1ac7 100644 --- a/include/Nazara/Core/StdLogger.hpp +++ b/include/Nazara/Core/StdLogger.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index e4949d441..f00c373e8 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index f4f1557d7..abd97c051 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index ba7f34ff7..30f88de00 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -239,6 +240,8 @@ namespace Nz static String Boolean(bool boolean); static int Compare(const String& first, const String& second); + static inline String Format(const char* format, ...); + static String FormatVA(const char* format, va_list arg); static String Number(float number); static String Number(double number); static String Number(long double number); diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index a5e099a3c..027ab4349 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -19,6 +19,23 @@ namespace Nz { } + /*! + * \brief Build a string using a format and returns it + * \return Formatted string + * + * \param format String format + * \param ... Format arguments + */ + String String::Format(const char* format, ...) + { + va_list args; + va_start(args, format); + String result = FormatVA(format, args); + va_end(args); + + return result; + } + /*! * \brief Releases the content to the string */ diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index f727ed35c..6898e5b6a 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/TaskScheduler.hpp b/include/Nazara/Core/TaskScheduler.hpp index 3a061168d..405e88ed3 100644 --- a/include/Nazara/Core/TaskScheduler.hpp +++ b/include/Nazara/Core/TaskScheduler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/TaskScheduler.inl b/include/Nazara/Core/TaskScheduler.inl index 96e240081..62b77447b 100644 --- a/include/Nazara/Core/TaskScheduler.inl +++ b/include/Nazara/Core/TaskScheduler.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index 4e4dd4efb..e129cbe40 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -32,11 +32,13 @@ namespace Nz Id GetId() const; bool IsJoinable() const; void Join(); + void SetName(const String& name); Thread& operator=(const Thread&) = delete; Thread& operator=(Thread&& thread); static unsigned int HardwareConcurrency(); + static void SetCurrentThreadName(const String& name); static void Sleep(UInt32 milliseconds); private: diff --git a/include/Nazara/Core/Thread.inl b/include/Nazara/Core/Thread.inl index f372c803f..f2065adfa 100644 --- a/include/Nazara/Core/Thread.inl +++ b/include/Nazara/Core/Thread.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ThreadSafety.hpp b/include/Nazara/Core/ThreadSafety.hpp index 5b1629b5b..271d6c474 100644 --- a/include/Nazara/Core/ThreadSafety.hpp +++ b/include/Nazara/Core/ThreadSafety.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/ThreadSafetyOff.hpp b/include/Nazara/Core/ThreadSafetyOff.hpp index 29c327e0d..196ef7d07 100644 --- a/include/Nazara/Core/ThreadSafetyOff.hpp +++ b/include/Nazara/Core/ThreadSafetyOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Unicode.hpp b/include/Nazara/Core/Unicode.hpp index a42e88e90..4dfb670a3 100644 --- a/include/Nazara/Core/Unicode.hpp +++ b/include/Nazara/Core/Unicode.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Core/Updatable.hpp b/include/Nazara/Core/Updatable.hpp index fd93dafe8..e1a7cf5a9 100644 --- a/include/Nazara/Core/Updatable.hpp +++ b/include/Nazara/Core/Updatable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Graphics/AbstractBackground.hpp b/include/Nazara/Graphics/AbstractBackground.hpp index 8e21326e5..7c6ce8348 100644 --- a/include/Nazara/Graphics/AbstractBackground.hpp +++ b/include/Nazara/Graphics/AbstractBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index a245787ab..0e3b94f2f 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -51,7 +51,7 @@ namespace Nz virtual void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) = 0; virtual void AddPointLight(const PointLight& light); virtual void AddSpotLight(const SpotLight& light); - virtual void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) = 0; + virtual void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay = nullptr) = 0; virtual void Clear(bool fully = false); diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index d13ac88ee..4279a5f39 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/AbstractViewer.hpp b/include/Nazara/Graphics/AbstractViewer.hpp index a38bb6bd7..21a62a890 100644 --- a/include/Nazara/Graphics/AbstractViewer.hpp +++ b/include/Nazara/Graphics/AbstractViewer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -33,6 +33,7 @@ namespace Nz virtual Vector3f GetForward() const = 0; virtual const Frustumf& GetFrustum() const = 0; virtual const Matrix4f& GetProjectionMatrix() const = 0; + virtual Nz::ProjectionType GetProjectionType() const = 0; virtual const RenderTarget* GetTarget() const = 0; virtual const Matrix4f& GetViewMatrix() const = 0; virtual const Recti& GetViewport() const = 0; diff --git a/include/Nazara/Graphics/Billboard.hpp b/include/Nazara/Graphics/Billboard.hpp index 68a64a4b5..c82a5d2bf 100644 --- a/include/Nazara/Graphics/Billboard.hpp +++ b/include/Nazara/Graphics/Billboard.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 45c2ef918..137524e95 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ColorBackground.hpp b/include/Nazara/Graphics/ColorBackground.hpp index 95113f71b..d76a92977 100644 --- a/include/Nazara/Graphics/ColorBackground.hpp +++ b/include/Nazara/Graphics/ColorBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -26,9 +26,9 @@ namespace Nz ColorBackground(const ColorBackground&) = default; ColorBackground(ColorBackground&&) = delete; - void Draw(const AbstractViewer* viewer) const; + void Draw(const AbstractViewer* viewer) const override; - BackgroundType GetBackgroundType() const; + BackgroundType GetBackgroundType() const override; Color GetColor() const; void SetColor(const Color& color); diff --git a/include/Nazara/Graphics/ColorBackground.inl b/include/Nazara/Graphics/ColorBackground.inl index 67b1f2558..30d870365 100644 --- a/include/Nazara/Graphics/ColorBackground.inl +++ b/include/Nazara/Graphics/ColorBackground.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ConfigCheck.hpp b/include/Nazara/Graphics/ConfigCheck.hpp index c2bbda886..3ec60640d 100644 --- a/include/Nazara/Graphics/ConfigCheck.hpp +++ b/include/Nazara/Graphics/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/CullingList.hpp b/include/Nazara/Graphics/CullingList.hpp index f8c50d83d..e484be81a 100644 --- a/include/Nazara/Graphics/CullingList.hpp +++ b/include/Nazara/Graphics/CullingList.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/CullingList.inl b/include/Nazara/Graphics/CullingList.inl index d4f80b3d7..270caefb3 100644 --- a/include/Nazara/Graphics/CullingList.inl +++ b/include/Nazara/Graphics/CullingList.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Debug.hpp b/include/Nazara/Graphics/Debug.hpp index 1d048c131..f20764d29 100644 --- a/include/Nazara/Graphics/Debug.hpp +++ b/include/Nazara/Graphics/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/DebugOff.hpp b/include/Nazara/Graphics/DebugOff.hpp index c90640fc0..325dc62f9 100644 --- a/include/Nazara/Graphics/DebugOff.hpp +++ b/include/Nazara/Graphics/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/DeferredBloomPass.hpp b/include/Nazara/Graphics/DeferredBloomPass.hpp index 5c45a2277..c00cc3c4c 100644 --- a/include/Nazara/Graphics/DeferredBloomPass.hpp +++ b/include/Nazara/Graphics/DeferredBloomPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -29,8 +29,8 @@ namespace Nz float GetBrightThreshold() const; Texture* GetTexture(unsigned int i) const; - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; - bool Resize(const Vector2ui& dimensions); + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; + bool Resize(const Vector2ui& dimensions) override; void SetBlurPassCount(unsigned int passCount); void SetBrightLuminance(float luminance); diff --git a/include/Nazara/Graphics/DeferredDOFPass.hpp b/include/Nazara/Graphics/DeferredDOFPass.hpp index c3d6e4c0f..b4025be7d 100644 --- a/include/Nazara/Graphics/DeferredDOFPass.hpp +++ b/include/Nazara/Graphics/DeferredDOFPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -23,8 +23,8 @@ namespace Nz DeferredDOFPass(); virtual ~DeferredDOFPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; - bool Resize(const Vector2ui& dimensions); + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; + bool Resize(const Vector2ui& dimensions) override; protected: RenderTexture m_dofRTT; diff --git a/include/Nazara/Graphics/DeferredFXAAPass.hpp b/include/Nazara/Graphics/DeferredFXAAPass.hpp index 1c74ffb1c..e8179f46d 100644 --- a/include/Nazara/Graphics/DeferredFXAAPass.hpp +++ b/include/Nazara/Graphics/DeferredFXAAPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredFXAAPass(); virtual ~DeferredFXAAPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; protected: RenderStates m_states; diff --git a/include/Nazara/Graphics/DeferredFinalPass.hpp b/include/Nazara/Graphics/DeferredFinalPass.hpp index f6b633925..d99c8ed30 100644 --- a/include/Nazara/Graphics/DeferredFinalPass.hpp +++ b/include/Nazara/Graphics/DeferredFinalPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredFinalPass(); virtual ~DeferredFinalPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; protected: RenderStates m_states; diff --git a/include/Nazara/Graphics/DeferredFogPass.hpp b/include/Nazara/Graphics/DeferredFogPass.hpp index babccb0bf..c1ccbdc88 100644 --- a/include/Nazara/Graphics/DeferredFogPass.hpp +++ b/include/Nazara/Graphics/DeferredFogPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredFogPass(); virtual ~DeferredFogPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; protected: RenderStates m_states; diff --git a/include/Nazara/Graphics/DeferredForwardPass.hpp b/include/Nazara/Graphics/DeferredForwardPass.hpp index cd5341d85..7fc619da2 100644 --- a/include/Nazara/Graphics/DeferredForwardPass.hpp +++ b/include/Nazara/Graphics/DeferredForwardPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -20,8 +20,8 @@ namespace Nz DeferredForwardPass(); virtual ~DeferredForwardPass(); - void Initialize(DeferredRenderTechnique* technique); - bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const; + void Initialize(DeferredRenderTechnique* technique) override; + bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const override; protected: const ForwardRenderTechnique* m_forwardTechnique; diff --git a/include/Nazara/Graphics/DeferredGeometryPass.hpp b/include/Nazara/Graphics/DeferredGeometryPass.hpp index 15437f0d8..b390263b6 100644 --- a/include/Nazara/Graphics/DeferredGeometryPass.hpp +++ b/include/Nazara/Graphics/DeferredGeometryPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -21,8 +21,8 @@ namespace Nz DeferredGeometryPass(); virtual ~DeferredGeometryPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; - bool Resize(const Vector2ui& dimensions); + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; + bool Resize(const Vector2ui& dimensions) override; protected: struct ShaderUniforms; diff --git a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp index 68eb96264..cbff41041 100644 --- a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp +++ b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -28,7 +28,7 @@ namespace Nz bool IsLightMeshesDrawingEnabled() const; - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const override; protected: LightUniforms m_directionalLightUniforms; diff --git a/include/Nazara/Graphics/DeferredRenderPass.hpp b/include/Nazara/Graphics/DeferredRenderPass.hpp index 7053bbaa5..784ad3c29 100644 --- a/include/Nazara/Graphics/DeferredRenderPass.hpp +++ b/include/Nazara/Graphics/DeferredRenderPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 922174df6..5f9f7538e 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -37,7 +37,7 @@ namespace Nz void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; void AddDrawable(int renderOrder, const Drawable* drawable) override; 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 AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay = nullptr) override; void Clear(bool fully = false) override; diff --git a/include/Nazara/Graphics/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp index 36ac47c8b..bdac459e9 100644 --- a/include/Nazara/Graphics/DeferredRenderTechnique.hpp +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index 81ec921c0..871cefa66 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -38,7 +38,7 @@ namespace Nz void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; void AddPointLight(const PointLight& light) override; void AddSpotLight(const SpotLight& light) override; - void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay = nullptr) override; private: inline bool IsMaterialSuitable(const Material* material) const; diff --git a/include/Nazara/Graphics/DepthRenderQueue.inl b/include/Nazara/Graphics/DepthRenderQueue.inl index 8fbce164b..7646c76a7 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.inl +++ b/include/Nazara/Graphics/DepthRenderQueue.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index 9d4ba601f..d28b8a5c4 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -55,7 +55,6 @@ namespace Nz NazaraSlot(Shader, OnShaderRelease, shaderReleaseSlot); // Autre uniformes - int eyePosition; int sceneAmbient; int textureOverlay; }; diff --git a/include/Nazara/Graphics/DepthRenderTechnique.inl b/include/Nazara/Graphics/DepthRenderTechnique.inl index ac6b052d0..9b32e7d42 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.inl +++ b/include/Nazara/Graphics/DepthRenderTechnique.inl @@ -1,3 +1,3 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Drawable.hpp b/include/Nazara/Graphics/Drawable.hpp index 5d5eca95b..13a2141b5 100644 --- a/include/Nazara/Graphics/Drawable.hpp +++ b/include/Nazara/Graphics/Drawable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index fd87cac6c..68a8ed95e 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -148,6 +148,26 @@ namespace Nz ShaderFlags_Max = ShaderFlags_VertexColor * 2 - 1 }; + + enum TextureMap + { + TextureMap_Alpha, + TextureMap_Diffuse, + TextureMap_Emissive, + TextureMap_Height, + TextureMap_ReflectionCube, + TextureMap_Normal, + TextureMap_Overlay, + TextureMap_Shadow2D_1, + TextureMap_Shadow2D_2, + TextureMap_Shadow2D_3, + TextureMap_ShadowCube_1, + TextureMap_ShadowCube_2, + TextureMap_ShadowCube_3, + TextureMap_Specular, + + TextureMap_Max = TextureMap_Specular + }; } #endif // NAZARA_ENUMS_GRAPHICS_HPP diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 56474a642..bc5c2456e 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,7 @@ namespace Nz void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; void AddDrawable(int renderOrder, const Drawable* drawable) override; 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 AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay = nullptr) override; void Clear(bool fully = false) override; @@ -73,7 +74,7 @@ namespace Nz std::vector billboards; }; - typedef std::map BatchedBillboardContainer; + using BatchedBillboardContainer = std::map; struct BatchedBillboardPipelineEntry { @@ -81,7 +82,7 @@ namespace Nz bool enabled = false; }; - typedef std::map BillboardPipelineBatches; + using BillboardPipelineBatches = std::map; /// Sprites struct SpriteChain_XYZ_Color_UV @@ -97,7 +98,7 @@ namespace Nz std::vector spriteChains; }; - typedef std::map SpriteOverlayBatches; + using SpriteOverlayBatches = std::map; struct BatchedBasicSpriteEntry { @@ -107,7 +108,7 @@ namespace Nz bool enabled = false; }; - typedef std::map SpriteMaterialBatches; + using SpriteMaterialBatches = std::map; struct BatchedSpritePipelineEntry { @@ -115,7 +116,7 @@ namespace Nz bool enabled = false; }; - typedef std::map SpritePipelineBatches; + using SpritePipelineBatches = std::map; /// Meshes struct MeshDataComparator @@ -132,7 +133,7 @@ namespace Nz Spheref squaredBoundingSphere; }; - typedef std::map MeshInstanceContainer; + using MeshInstanceContainer = std::map; struct BatchedModelEntry { @@ -142,7 +143,7 @@ namespace Nz bool enabled = false; }; - typedef std::map MeshMaterialBatches; + using MeshMaterialBatches = std::map; struct BatchedMaterialEntry { @@ -150,25 +151,33 @@ namespace Nz MeshMaterialBatches materialMap; }; - typedef std::map MeshPipelineBatches; + using MeshPipelineBatches = std::map; - struct TransparentModelData + struct UnbatchedModelData { Matrix4f transformMatrix; MeshData meshData; - Spheref squaredBoundingSphere; + Spheref obbSphere; const Material* material; }; - typedef std::vector TransparentModelContainer; + struct UnbatchedSpriteData + { + std::size_t spriteCount; + const Material* material; + const Texture* overlay; + const VertexStruct_XYZ_Color_UV* vertices; + }; struct Layer { BillboardPipelineBatches billboards; - SpritePipelineBatches basicSprites; + SpritePipelineBatches opaqueSprites; MeshPipelineBatches opaqueModels; - TransparentModelContainer transparentModels; - std::vector transparentModelData; + std::vector depthSortedMeshes; + std::vector depthSortedSprites; + std::vector depthSortedMeshData; + std::vector depthSortedSpriteData; std::vector otherDrawables; unsigned int clearCount = 0; }; @@ -179,6 +188,10 @@ namespace Nz BillboardData* GetBillboardData(int renderOrder, const Material* material, unsigned int count); Layer& GetLayer(int i); ///TODO: Inline + void SortBillboards(Layer& layer, const Planef& nearPlane); + void SortForOrthographic(const AbstractViewer* viewer); + void SortForPerspective(const AbstractViewer* viewer); + void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); void OnMaterialInvalidation(const Material* material); void OnTextureInvalidation(const Texture* texture); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 5d82c4bf9..cadb60473 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -43,10 +43,11 @@ namespace Nz void DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; void DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; void DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawOrderedSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; void DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; void OnShaderInvalidated(const Shader* shader) const; - void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const; + void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int lightIndex, unsigned int uniformOffset) const; static float ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light); static float ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 5f7ba181f..ae22668ec 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -6,135 +6,6 @@ namespace Nz { - /*! - * \brief Sens the uniforms for light - * - * \param shader Shader to send uniforms to - * \param uniforms Uniforms to send - * \param index Index of the light - * \param uniformOffset Offset for the uniform - * \param availableTextureUnit Unit texture available - */ - - inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const - { - // If anyone got a better idea.. - int dummyCubemap = Renderer::GetMaxTextureUnits() - 1; - int dummyTexture = Renderer::GetMaxTextureUnits() - 2; - - if (index < m_lights.size()) - { - const LightIndex& lightIndex = m_lights[index]; - - shader->SendInteger(uniforms.locations.type + uniformOffset, lightIndex.type); //< Sends the light type - - switch (lightIndex.type) - { - case LightType_Directional: - { - const auto& light = m_renderQueue.directionalLights[lightIndex.index]; - - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); - - if (uniforms.locations.shadowMapping != -1) - shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); - - if (light.shadowMap) - { - Renderer::SetTexture(availableTextureUnit, light.shadowMap); - Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); - - if (uniforms.locations.lightViewProjMatrix != -1) - shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); - } - else if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - break; - } - - case LightType_Point: - { - const auto& light = m_renderQueue.pointLights[lightIndex.index]; - - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); - shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius)); - - if (uniforms.locations.shadowMapping != -1) - shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); - - if (light.shadowMap) - { - Renderer::SetTexture(availableTextureUnit, light.shadowMap); - Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); - - if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit); - } - else if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - break; - } - - case LightType_Spot: - { - const auto& light = m_renderQueue.spotLights[lightIndex.index]; - - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); - shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); - shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); - - if (uniforms.locations.shadowMapping != -1) - shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); - - if (light.shadowMap) - { - Renderer::SetTexture(availableTextureUnit, light.shadowMap); - Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); - - if (uniforms.locations.lightViewProjMatrix != -1) - shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); - } - else if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - - if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - - break; - } - } - } - else - { - if (uniforms.locations.type != -1) - shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - - if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - } - } - /*! * \brief Computes the score for directional light * \return 0.f @@ -163,7 +34,7 @@ namespace Nz inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light) { ///TODO: Compute a score depending on the light luminosity - return object.SquaredDistance(light.position); + return object.GetPosition().SquaredDistance(light.position); } /*! @@ -177,7 +48,7 @@ namespace Nz inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light) { ///TODO: Compute a score depending on the light luminosity and spot direction - return object.SquaredDistance(light.position); + return object.GetPosition().SquaredDistance(light.position); } /*! @@ -199,29 +70,29 @@ namespace Nz /*! * \brief Checks whether the point light is suitable for the computations - * \return true if light is enoughly close + * \return true if light is close enough * - * \param object Sphere symbolising the object + * \param object Sphere symbolizing the object * \param light Light to compute */ inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light) { // If the object is too far away from this point light, there is not way it could light it - return object.SquaredDistance(light.position) <= light.radius * light.radius; + return object.Intersect(Spheref(light.position, light.radius)); } /*! * \brief Checks whether the spot light is suitable for the computations - * \return true if light is enoughly close + * \return true if light is close enough * - * \param object Sphere symbolising the object + * \param object Sphere symbolizing the object * \param light Light to compute */ inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light) { ///TODO: Exclude spot lights based on their direction and outer angle? - return object.SquaredDistance(light.position) <= light.radius * light.radius; + return object.Intersect(Spheref(light.position, light.radius)); } } diff --git a/include/Nazara/Graphics/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index e2aef76ba..499837466 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp index 42449712c..3c5aa2d4b 100644 --- a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp +++ b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 3f117c84b..1f7ec8314 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/InstancedRenderable.inl b/include/Nazara/Graphics/InstancedRenderable.inl index 5ee49dc6a..47e47eac1 100644 --- a/include/Nazara/Graphics/InstancedRenderable.inl +++ b/include/Nazara/Graphics/InstancedRenderable.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 071b748c3..8574bb783 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -102,13 +102,11 @@ namespace Nz { int type; int color; - int directionalSpotLightShadowMap; int factors; int lightViewProjMatrix; int parameters1; int parameters2; int parameters3; - int pointLightShadowMap; int shadowMapping; }; diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index 2852834b7..b30daaf60 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index f7d15d6fe..bf14b1792 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -64,7 +64,7 @@ namespace Nz inline Material(const Material& material); inline ~Material(); - void Apply(const MaterialPipeline::Instance& instance, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; + void Apply(const MaterialPipeline::Instance& instance) const; void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams()); @@ -174,6 +174,7 @@ namespace Nz inline Material& operator=(const Material& material); inline static MaterialRef GetDefault(); + inline static int GetTextureUnit(TextureMap textureMap); template static MaterialRef New(Args&&... args); // Signals: @@ -207,6 +208,7 @@ namespace Nz float m_alphaThreshold; float m_shininess; + static std::array s_textureUnits; static MaterialLibrary::LibraryMap s_library; static MaterialLoader::LoaderList s_loaders; static MaterialManager::ManagerMap s_managerMap; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index cec965e6e..61f2220d4 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -1356,6 +1356,11 @@ namespace Nz return s_defaultMaterial; } + inline int Material::GetTextureUnit(TextureMap textureMap) + { + return s_textureUnits[textureMap]; + } + inline void Material::InvalidatePipeline() { m_pipelineUpdated = false; diff --git a/include/Nazara/Graphics/MaterialPipeline.hpp b/include/Nazara/Graphics/MaterialPipeline.hpp index cf64d5e40..79028ac45 100644 --- a/include/Nazara/Graphics/MaterialPipeline.hpp +++ b/include/Nazara/Graphics/MaterialPipeline.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/MaterialPipeline.inl b/include/Nazara/Graphics/MaterialPipeline.inl index 0cbea4e61..263dbcad3 100644 --- a/include/Nazara/Graphics/MaterialPipeline.inl +++ b/include/Nazara/Graphics/MaterialPipeline.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index b1755c7d8..e512e5201 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index 8e659e869..7925e9e70 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp index 05537ba55..5012c82d2 100644 --- a/include/Nazara/Graphics/ParticleController.hpp +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleDeclaration.hpp b/include/Nazara/Graphics/ParticleDeclaration.hpp index 770cbe31d..db5519d24 100644 --- a/include/Nazara/Graphics/ParticleDeclaration.hpp +++ b/include/Nazara/Graphics/ParticleDeclaration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleDeclaration.inl b/include/Nazara/Graphics/ParticleDeclaration.inl index dafa2653a..efbb4fd39 100644 --- a/include/Nazara/Graphics/ParticleDeclaration.inl +++ b/include/Nazara/Graphics/ParticleDeclaration.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index cfbb9e98a..c085c9062 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleFunctionController.hpp b/include/Nazara/Graphics/ParticleFunctionController.hpp index 6b3c4a974..c61197fc2 100644 --- a/include/Nazara/Graphics/ParticleFunctionController.hpp +++ b/include/Nazara/Graphics/ParticleFunctionController.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleFunctionController.inl b/include/Nazara/Graphics/ParticleFunctionController.inl index eb4365fda..92e78e4af 100644 --- a/include/Nazara/Graphics/ParticleFunctionController.inl +++ b/include/Nazara/Graphics/ParticleFunctionController.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleFunctionGenerator.hpp b/include/Nazara/Graphics/ParticleFunctionGenerator.hpp index 7aa5bb9f3..63d7fd755 100644 --- a/include/Nazara/Graphics/ParticleFunctionGenerator.hpp +++ b/include/Nazara/Graphics/ParticleFunctionGenerator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleFunctionGenerator.inl b/include/Nazara/Graphics/ParticleFunctionGenerator.inl index 9cb11683c..787e1cdce 100644 --- a/include/Nazara/Graphics/ParticleFunctionGenerator.inl +++ b/include/Nazara/Graphics/ParticleFunctionGenerator.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleFunctionRenderer.hpp b/include/Nazara/Graphics/ParticleFunctionRenderer.hpp index 810027ae9..b4d8772df 100644 --- a/include/Nazara/Graphics/ParticleFunctionRenderer.hpp +++ b/include/Nazara/Graphics/ParticleFunctionRenderer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleFunctionRenderer.inl b/include/Nazara/Graphics/ParticleFunctionRenderer.inl index cf859fbfe..12b53bf88 100644 --- a/include/Nazara/Graphics/ParticleFunctionRenderer.inl +++ b/include/Nazara/Graphics/ParticleFunctionRenderer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp index d072ae346..d4fcb71fa 100644 --- a/include/Nazara/Graphics/ParticleGenerator.hpp +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleGroup.hpp b/include/Nazara/Graphics/ParticleGroup.hpp index 460694160..93d3f63d4 100644 --- a/include/Nazara/Graphics/ParticleGroup.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleGroup.inl b/include/Nazara/Graphics/ParticleGroup.inl index f0e205346..330d6546f 100644 --- a/include/Nazara/Graphics/ParticleGroup.inl +++ b/include/Nazara/Graphics/ParticleGroup.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleMapper.hpp b/include/Nazara/Graphics/ParticleMapper.hpp index ffbe2a5ad..ba5a8e0f1 100644 --- a/include/Nazara/Graphics/ParticleMapper.hpp +++ b/include/Nazara/Graphics/ParticleMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleMapper.inl b/include/Nazara/Graphics/ParticleMapper.inl index 1a4566c33..289fdf045 100644 --- a/include/Nazara/Graphics/ParticleMapper.inl +++ b/include/Nazara/Graphics/ParticleMapper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp index 2ddca18b3..4549d0701 100644 --- a/include/Nazara/Graphics/ParticleRenderer.hpp +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/ParticleStruct.hpp b/include/Nazara/Graphics/ParticleStruct.hpp index b4f55a3a1..4e14ab9ca 100644 --- a/include/Nazara/Graphics/ParticleStruct.hpp +++ b/include/Nazara/Graphics/ParticleStruct.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/RenderTechniques.hpp b/include/Nazara/Graphics/RenderTechniques.hpp index a4642ffc8..79fb0c629 100644 --- a/include/Nazara/Graphics/RenderTechniques.hpp +++ b/include/Nazara/Graphics/RenderTechniques.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Renderable.hpp b/include/Nazara/Graphics/Renderable.hpp index 412caa301..62cf861c6 100644 --- a/include/Nazara/Graphics/Renderable.hpp +++ b/include/Nazara/Graphics/Renderable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Renderable.inl b/include/Nazara/Graphics/Renderable.inl index 804567814..4c572a1cb 100644 --- a/include/Nazara/Graphics/Renderable.inl +++ b/include/Nazara/Graphics/Renderable.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/SceneData.hpp b/include/Nazara/Graphics/SceneData.hpp index 94aafbda4..d6e54cc1b 100644 --- a/include/Nazara/Graphics/SceneData.hpp +++ b/include/Nazara/Graphics/SceneData.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 99791168a..bb427a3e2 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/SkinningManager.hpp b/include/Nazara/Graphics/SkinningManager.hpp index a8f76768e..040964428 100644 --- a/include/Nazara/Graphics/SkinningManager.hpp +++ b/include/Nazara/Graphics/SkinningManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index 95ce2872a..4f433ed3e 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl index 6171f1e28..3379ca9d1 100644 --- a/include/Nazara/Graphics/SkyboxBackground.inl +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 2c42f4ce1..3625708da 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index deec75959..c9f698371 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 3e05c2795..19a3ec1a7 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index d5db90805..c7ba17585 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/TextureBackground.hpp b/include/Nazara/Graphics/TextureBackground.hpp index 741c974b7..bdb088812 100644 --- a/include/Nazara/Graphics/TextureBackground.hpp +++ b/include/Nazara/Graphics/TextureBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -24,9 +24,9 @@ namespace Nz public: TextureBackground(TextureRef texture = TextureRef()); - void Draw(const AbstractViewer* viewer) const; + void Draw(const AbstractViewer* viewer) const override; - BackgroundType GetBackgroundType() const; + BackgroundType GetBackgroundType() const override; inline const TextureRef& GetTexture() const; inline void SetTexture(TextureRef texture); diff --git a/include/Nazara/Graphics/TextureBackground.inl b/include/Nazara/Graphics/TextureBackground.inl index 31067f36c..7686fa466 100644 --- a/include/Nazara/Graphics/TextureBackground.inl +++ b/include/Nazara/Graphics/TextureBackground.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/TileMap.hpp b/include/Nazara/Graphics/TileMap.hpp index 02371c33c..dbc36aff5 100644 --- a/include/Nazara/Graphics/TileMap.hpp +++ b/include/Nazara/Graphics/TileMap.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl index f8faa7b54..0ed57a1be 100644 --- a/include/Nazara/Graphics/TileMap.inl +++ b/include/Nazara/Graphics/TileMap.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua.hpp b/include/Nazara/Lua.hpp index a0e68204c..bd7ddb24c 100644 --- a/include/Nazara/Lua.hpp +++ b/include/Nazara/Lua.hpp @@ -33,6 +33,8 @@ #include #include #include +#include #include +#include #endif // NAZARA_GLOBAL_LUA_HPP diff --git a/include/Nazara/Lua/ConfigCheck.hpp b/include/Nazara/Lua/ConfigCheck.hpp index 1701205c8..ee3010113 100644 --- a/include/Nazara/Lua/ConfigCheck.hpp +++ b/include/Nazara/Lua/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/Debug.hpp b/include/Nazara/Lua/Debug.hpp index 8cfefe4fc..991f620a2 100644 --- a/include/Nazara/Lua/Debug.hpp +++ b/include/Nazara/Lua/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/DebugOff.hpp b/include/Nazara/Lua/DebugOff.hpp index 3609f245d..59c38fd94 100644 --- a/include/Nazara/Lua/DebugOff.hpp +++ b/include/Nazara/Lua/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/Enums.hpp b/include/Nazara/Lua/Enums.hpp index 93068314f..f62357e6f 100644 --- a/include/Nazara/Lua/Enums.hpp +++ b/include/Nazara/Lua/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/Lua.hpp b/include/Nazara/Lua/Lua.hpp index e41de7e1e..e1c084f8f 100644 --- a/include/Nazara/Lua/Lua.hpp +++ b/include/Nazara/Lua/Lua.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 3085aed0f..451f91c08 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -26,13 +26,13 @@ namespace Nz friend class LuaClass; public: - using ClassFunc = std::function; - using ClassIndexFunc = std::function; - using ConstructorFunc = std::function; + 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; + using FinalizerFunc = std::function; + using StaticIndexFunc = std::function; + using StaticFunc = std::function; LuaClass() = default; LuaClass(const String& name); @@ -54,9 +54,9 @@ namespace Nz void Reset(); void Reset(const String& name); - void Register(LuaInstance& lua); + void Register(LuaState& state); - void PushGlobalTable(LuaInstance& lua); + void PushGlobalTable(LuaState& state); void SetConstructor(ConstructorFunc constructor); void SetFinalizer(FinalizerFunc finalizer); @@ -69,18 +69,18 @@ namespace Nz template friend struct LuaClassImplFinalizerSetupProxy; - void PushClassInfo(LuaInstance& lua); - void SetupConstructor(LuaInstance& lua); - void SetupDefaultToString(LuaInstance& lua); - void SetupFinalizer(LuaInstance& lua); - void SetupGetter(LuaInstance& lua, LuaCFunction proxy); - void SetupGlobalTable(LuaInstance& lua); - void SetupMetatable(LuaInstance& lua); - void SetupMethod(LuaInstance& lua, LuaCFunction proxy, const String& name, std::size_t methodIndex); - void SetupSetter(LuaInstance& lua, LuaCFunction proxy); + void PushClassInfo(LuaState& state); + void SetupConstructor(LuaState& state); + void SetupDefaultToString(LuaState& state); + void SetupFinalizer(LuaState& state); + void SetupGetter(LuaState& state, LuaCFunction proxy); + void SetupGlobalTable(LuaState& state); + void SetupMetatable(LuaState& state); + void SetupMethod(LuaState& state, LuaCFunction proxy, const String& name, std::size_t methodIndex); + void SetupSetter(LuaState& state, LuaCFunction proxy); - using ParentFunc = std::function; - using InstanceGetter = std::function; + using ParentFunc = std::function; + using InstanceGetter = std::function; struct ClassInfo { @@ -98,17 +98,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); - static int ToStringProxy(lua_State* state); + static int ConstructorProxy(lua_State* internalState); + static int FinalizerProxy(lua_State* internalState); + static int InfoDestructor(lua_State* internalState); + static void Get(const std::shared_ptr& info, LuaState& state, T* instance); + static int GetterProxy(lua_State* internalState); + static int MethodProxy(lua_State* internalState); + static int SetterProxy(lua_State* internalState); + static int StaticGetterProxy(lua_State* internalState); + static int StaticMethodProxy(lua_State* internalState); + static int StaticSetterProxy(lua_State* internalState); + static int ToStringProxy(lua_State* internalState); std::map m_methods; std::map m_staticMethods; diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 3168ba43d..40b7374bc 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -19,9 +19,9 @@ namespace Nz template inline void LuaClass::BindDefaultConstructor() { - SetConstructor([] (Nz::LuaInstance& lua, T* instance, std::size_t argumentCount) + SetConstructor([] (Nz::LuaState& state, T* instance, std::size_t argumentCount) { - NazaraUnused(lua); + NazaraUnused(state); NazaraUnused(argumentCount); PlacementNew(instance); @@ -47,14 +47,14 @@ namespace Nz std::shared_ptr::ClassInfo>& parentInfo = parent.m_info; - parentInfo->instanceGetters[m_info->name] = [info = m_info, convertFunc] (LuaInstance& lua) -> P* + parentInfo->instanceGetters[m_info->name] = [info = m_info, convertFunc] (LuaState& state) -> P* { - return convertFunc(static_cast(lua.CheckUserdata(1, info->name))); + return convertFunc(static_cast(state.CheckUserdata(1, info->name))); }; - m_info->parentGetters.emplace_back([parentInfo, convertFunc] (LuaInstance& lua, T* instance) + m_info->parentGetters.emplace_back([parentInfo, convertFunc] (LuaState& state, T* instance) { - LuaClass

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

::Get(parentInfo, state, convertFunc(instance)); }); } @@ -71,30 +71,30 @@ namespace Nz m_info = std::make_shared(); m_info->name = name; - m_info->instanceGetters[m_info->name] = [info = m_info] (LuaInstance& instance) + m_info->instanceGetters[m_info->name] = [info = m_info] (LuaState& state) { - return static_cast(instance.CheckUserdata(1, info->name)); + return static_cast(state.CheckUserdata(1, info->name)); }; } template - void LuaClass::Register(LuaInstance& lua) + void LuaClass::Register(LuaState& state) { - PushClassInfo(lua); + PushClassInfo(state); - // Let's create the metatable which will be associated with every instance. - SetupMetatable(lua); + // Let's create the metatable which will be associated with every state. + SetupMetatable(state); if (m_info->constructor || m_info->staticGetter || m_info->staticSetter || !m_staticMethods.empty()) - SetupGlobalTable(lua); + SetupGlobalTable(state); - lua.Pop(); // Pop our ClassInfo, which is now referenced by all our functions + state.Pop(); // Pop our ClassInfo, which is now referenced by all our functions } template - void LuaClass::PushGlobalTable(LuaInstance& lua) + void LuaClass::PushGlobalTable(LuaState& state) { - lua.PushReference(m_info->globalTableRef); + state.PushReference(m_info->globalTableRef); } template @@ -127,11 +127,11 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int + BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int { - handler.ProcessArguments(lua); + handler.ProcessArguments(state); - return handler.Invoke(lua, object, func); + return handler.Invoke(state, object, func); }); } @@ -141,11 +141,11 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int + BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int { - handler.ProcessArguments(lua); + handler.ProcessArguments(state); - return handler.Invoke(lua, object, func); + return handler.Invoke(state, object, func); }); } @@ -155,11 +155,11 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int + BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int { - handler.ProcessArguments(lua); + handler.ProcessArguments(state); - return handler.Invoke(lua, object, func); + return handler.Invoke(state, object, func); }); } @@ -169,11 +169,11 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int + BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int { - handler.ProcessArguments(lua); + handler.ProcessArguments(state); - return handler.Invoke(lua, object, func); + return handler.Invoke(state, object, func); }); } @@ -201,11 +201,11 @@ namespace Nz { typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - BindStaticMethod(name, [func, handler] (LuaInstance& lua) -> int + BindStaticMethod(name, [func, handler] (LuaState& state) -> int { - handler.ProcessArguments(lua); + handler.ProcessArguments(state); - return handler.Invoke(lua, func); + return handler.Invoke(state, func); }); } @@ -216,37 +216,37 @@ namespace Nz } template - void LuaClass::PushClassInfo(LuaInstance& lua) + void LuaClass::PushClassInfo(LuaState& state) { // Our ClassInfo has to outlive the LuaClass, because we don't want to force the user to keep the LuaClass alive // To do that, each Registration creates a tiny shared_ptr wrapper whose life is directly managed by Lua. // This shared_ptr object gets pushed as a up-value for every proxy function set in the metatable. // This way, there is no way our ClassInfo gets freed before any instance and the global class gets destroyed. - std::shared_ptr* info = static_cast*>(lua.PushUserdata(sizeof(std::shared_ptr))); + std::shared_ptr* info = static_cast*>(state.PushUserdata(sizeof(std::shared_ptr))); PlacementNew(info, m_info); // Setup a tiny metatable to let Lua know how to destroy our ClassInfo - lua.PushTable(0, 1); - lua.PushLightUserdata(info); - lua.PushCFunction(InfoDestructor, 1); - lua.SetField("__gc"); - lua.SetMetatable(-2); + state.PushTable(0, 1); + state.PushLightUserdata(info); + state.PushCFunction(InfoDestructor, 1); + state.SetField("__gc"); + state.SetMetatable(-2); } template - void LuaClass::SetupConstructor(LuaInstance& lua) + void LuaClass::SetupConstructor(LuaState& state) { - lua.PushValue(1); // ClassInfo - lua.PushCFunction(ConstructorProxy, 1); - lua.SetField("__call"); // ClassMeta.__call = ConstructorProxy + state.PushValue(1); // ClassInfo + state.PushCFunction(ConstructorProxy, 1); + state.SetField("__call"); // ClassMeta.__call = ConstructorProxy } template - void LuaClass::SetupDefaultToString(LuaInstance& lua) + void LuaClass::SetupDefaultToString(LuaState& state) { - lua.PushValue(1); // shared_ptr on UserData - lua.PushCFunction(ToStringProxy, 1); - lua.SetField("__tostring"); + state.PushValue(1); // shared_ptr on UserData + state.PushCFunction(ToStringProxy, 1); + state.SetField("__tostring"); } template @@ -255,61 +255,61 @@ namespace Nz template struct LuaClassImplFinalizerSetupProxy { - static void Setup(LuaInstance& lua) + static void Setup(LuaState& state) { - lua.PushValue(1); // ClassInfo - lua.PushCFunction(LuaClass::FinalizerProxy, 1); - lua.SetField("__gc"); + state.PushValue(1); // ClassInfo + state.PushCFunction(LuaClass::FinalizerProxy, 1); + state.SetField("__gc"); } }; template struct LuaClassImplFinalizerSetupProxy { - static void Setup(LuaInstance&) + static void Setup(LuaState&) { } }; template - void LuaClass::SetupFinalizer(LuaInstance& lua) + void LuaClass::SetupFinalizer(LuaState& state) { - LuaClassImplFinalizerSetupProxy::value>::Setup(lua); + LuaClassImplFinalizerSetupProxy::value>::Setup(state); } template - void LuaClass::SetupGetter(LuaInstance& lua, LuaCFunction proxy) + void LuaClass::SetupGetter(LuaState& state, LuaCFunction proxy) { - lua.PushValue(1); // ClassInfo - lua.PushValue(-2); // Metatable - lua.PushCFunction(proxy, 2); + state.PushValue(1); // ClassInfo + state.PushValue(-2); // Metatable + state.PushCFunction(proxy, 2); - lua.SetField("__index"); // Getter + state.SetField("__index"); // Getter } template - void LuaClass::SetupGlobalTable(LuaInstance& lua) + void LuaClass::SetupGlobalTable(LuaState& state) { // Create the global table - lua.PushTable(); // Class = {} + state.PushTable(); // Class = {} // Create a metatable which will be used for our global table - lua.PushTable(); // ClassMeta = {} + state.PushTable(); // ClassMeta = {} if (m_info->constructor) - SetupConstructor(lua); + SetupConstructor(state); if (m_info->staticGetter) - SetupGetter(lua, StaticGetterProxy); + SetupGetter(state, StaticGetterProxy); else { // Optimize by assigning the metatable instead of a search function - lua.PushValue(-1); // Metatable - lua.SetField("__index"); + state.PushValue(-1); // Metatable + state.SetField("__index"); } if (m_info->staticSetter) - SetupSetter(lua, StaticSetterProxy); + SetupSetter(state, StaticSetterProxy); m_info->staticMethods.reserve(m_staticMethods.size()); for (auto& pair : m_staticMethods) @@ -317,41 +317,41 @@ namespace Nz std::size_t methodIndex = m_info->staticMethods.size(); m_info->staticMethods.push_back(pair.second); - SetupMethod(lua, StaticMethodProxy, pair.first, methodIndex); + SetupMethod(state, StaticMethodProxy, pair.first, methodIndex); } - lua.SetMetatable(-2); // setmetatable(Class, ClassMeta), pops ClassMeta + state.SetMetatable(-2); // setmetatable(Class, ClassMeta), pops ClassMeta - lua.PushValue(-1); // As CreateReference() pops the table, push a copy - m_info->globalTableRef = lua.CreateReference(); + state.PushValue(-1); // As CreateReference() pops the table, push a copy + m_info->globalTableRef = state.CreateReference(); - lua.SetGlobal(m_info->name); // _G["Class"] = Class + state.SetGlobal(m_info->name); // _G["Class"] = Class } template - void LuaClass::SetupMetatable(LuaInstance& lua) + void LuaClass::SetupMetatable(LuaState& state) { - if (!lua.NewMetatable(m_info->name)) + if (!state.NewMetatable(m_info->name)) NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance"); { - SetupFinalizer(lua); + SetupFinalizer(state); if (m_info->getter || !m_info->parentGetters.empty()) - SetupGetter(lua, GetterProxy); + SetupGetter(state, GetterProxy); else { // Optimize by assigning the metatable instead of a search function // This is only possible if we have no custom getter nor parent - lua.PushValue(-1); // Metatable - lua.SetField("__index"); + state.PushValue(-1); // Metatable + state.SetField("__index"); } if (m_info->setter) - SetupSetter(lua, SetterProxy); + SetupSetter(state, SetterProxy); // In case a __tostring method is missing, add a default implementation returning the class name if (m_methods.find("__tostring") == m_methods.end()) - SetupDefaultToString(lua); + SetupDefaultToString(state); m_info->methods.reserve(m_methods.size()); for (auto& pair : m_methods) @@ -359,80 +359,80 @@ namespace Nz std::size_t methodIndex = m_info->methods.size(); m_info->methods.push_back(pair.second); - SetupMethod(lua, MethodProxy, pair.first, methodIndex); + SetupMethod(state, MethodProxy, pair.first, methodIndex); } } - lua.Pop(); //< Pops the metatable, it won't be collected before it's referenced by the Lua registry. + state.Pop(); //< Pops the metatable, it won't be collected before it's referenced by the Lua registry. } template - void LuaClass::SetupMethod(LuaInstance& lua, LuaCFunction proxy, const String& name, std::size_t methodIndex) + void LuaClass::SetupMethod(LuaState& state, LuaCFunction proxy, const String& name, std::size_t methodIndex) { - lua.PushValue(1); // ClassInfo - lua.PushInteger(methodIndex); - lua.PushCFunction(proxy, 2); + state.PushValue(1); // ClassInfo + state.PushInteger(methodIndex); + state.PushCFunction(proxy, 2); - lua.SetField(name); // Method name + state.SetField(name); // Method name } template - void LuaClass::SetupSetter(LuaInstance& lua, LuaCFunction proxy) + void LuaClass::SetupSetter(LuaState& state, LuaCFunction proxy) { - lua.PushValue(1); // ClassInfo - lua.PushCFunction(proxy, 1); + state.PushValue(1); // ClassInfo + state.PushCFunction(proxy, 1); - lua.SetField("__newindex"); // Setter + state.SetField("__newindex"); // Setter } template - int LuaClass::ConstructorProxy(lua_State* state) + int LuaClass::ConstructorProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); const ConstructorFunc& constructor = info->constructor; - lua.Remove(1); // On enlève l'argument "table" du stack + state.Remove(1); // On enlève l'argument "table" du stack - std::size_t argCount = lua.GetStackTop(); + std::size_t argCount = state.GetStackTop(); - T* instance = static_cast(lua.PushUserdata(sizeof(T))); + T* instance = static_cast(state.PushUserdata(sizeof(T))); - if (!constructor(lua, instance, argCount)) + if (!constructor(state, instance, argCount)) { - lua.Error("Constructor failed"); + state.Error("Constructor failed"); return 0; // Normalement jamais exécuté (l'erreur provoquant une exception) } - lua.SetMetatable(info->name); + state.SetMetatable(info->name); return 1; } template - int LuaClass::FinalizerProxy(lua_State* state) + int LuaClass::FinalizerProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.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 + T* instance = static_cast(state.CheckUserdata(1, info->name)); + state.Remove(1); //< Remove the instance from the Lua stack - if (!finalizer || finalizer(lua, *instance)) + if (!finalizer || finalizer(state, *instance)) instance->~T(); return 0; } template - int LuaClass::InfoDestructor(lua_State* state) + int LuaClass::InfoDestructor(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - lua.DestroyReference(info->globalTableRef); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); + state.DestroyReference(info->globalTableRef); using namespace std; // Obligatoire pour le destructeur info.~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur @@ -441,27 +441,27 @@ namespace Nz } template - void LuaClass::Get(const std::shared_ptr& info, LuaInstance& lua, T* instance) + void LuaClass::Get(const std::shared_ptr& info, LuaState& state, T* instance) { const ClassIndexFunc& getter = info->getter; - if (!getter || !getter(lua, *instance)) + if (!getter || !getter(state, *instance)) { // Query from the metatable - lua.GetMetatable(info->name); //< Metatable - lua.PushValue(2); //< Field - lua.GetTable(); // Metatable[Field] + state.GetMetatable(info->name); //< Metatable + state.PushValue(2); //< Field + state.GetTable(); // Metatable[Field] - lua.Remove(-2); // Remove Metatable + state.Remove(-2); // Remove Metatable - if (!lua.IsValid(-1)) + if (!state.IsValid(-1)) { for (const ParentFunc& parentGetter : info->parentGetters) { - lua.Pop(); //< Pop the last nil value + state.Pop(); //< Pop the last nil value - parentGetter(lua, instance); - if (lua.IsValid(-1)) + parentGetter(state, instance); + if (state.IsValid(-1)) return; } } @@ -469,131 +469,131 @@ namespace Nz } template - int LuaClass::GetterProxy(lua_State* state) + int LuaClass::GetterProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); - T* instance = static_cast(lua.CheckUserdata(1, info->name)); + T* instance = static_cast(state.CheckUserdata(1, info->name)); - Get(info, lua, instance); + Get(info, state, instance); return 1; } template - int LuaClass::MethodProxy(lua_State* state) + int LuaClass::MethodProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); T* instance = nullptr; - if (lua.GetMetatable(1)) + if (state.GetMetatable(1)) { - LuaType type = lua.GetField("__name"); + LuaType type = state.GetField("__name"); if (type == LuaType_String) { - String name = lua.ToString(-1); + String name = state.ToString(-1); auto it = info->instanceGetters.find(name); if (it != info->instanceGetters.end()) - instance = it->second(lua); + instance = it->second(state); } - lua.Pop(2); + state.Pop(2); } if (!instance) { - lua.Error("Method cannot be called without an object"); + state.Error("Method cannot be called without an object"); return 0; } - std::size_t argCount = lua.GetStackTop() - 1U; + std::size_t argCount = state.GetStackTop() - 1U; - unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); + unsigned int index = static_cast(state.ToInteger(state.GetIndexOfUpValue(2))); const ClassFunc& method = info->methods[index]; - return method(lua, *instance, argCount); + return method(state, *instance, argCount); } template - int LuaClass::SetterProxy(lua_State* state) + int LuaClass::SetterProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); const ClassIndexFunc& setter = info->setter; - T& instance = *static_cast(lua.CheckUserdata(1, info->name)); + T& instance = *static_cast(state.CheckUserdata(1, info->name)); - if (!setter(lua, instance)) + if (!setter(state, instance)) { std::size_t length; - const char* str = lua.ToString(2, &length); + const char* str = state.ToString(2, &length); - lua.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + "\")"); + state.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + "\")"); } return 1; } template - int LuaClass::StaticGetterProxy(lua_State* state) + int LuaClass::StaticGetterProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); const StaticIndexFunc& getter = info->staticGetter; - if (!getter(lua)) + if (!getter(state)) { // On accède alors à la table - lua.PushValue(lua.GetIndexOfUpValue(2)); - lua.PushValue(-2); - lua.GetTable(); + state.PushValue(state.GetIndexOfUpValue(2)); + state.PushValue(-2); + state.GetTable(); } return 1; } template - int LuaClass::StaticMethodProxy(lua_State* state) + int LuaClass::StaticMethodProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); + unsigned int index = static_cast(state.ToInteger(state.GetIndexOfUpValue(2))); const StaticFunc& method = info->staticMethods[index]; - return method(lua); + return method(state); } template - int LuaClass::StaticSetterProxy(lua_State* state) + int LuaClass::StaticSetterProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); const StaticIndexFunc& setter = info->staticSetter; - if (!setter(lua)) + if (!setter(state)) { std::size_t length; - const char* str = lua.ToString(2, &length); + const char* str = state.ToString(2, &length); - lua.Error("Class \"" + info->name + "\" has no static field \"" + String(str, length) + ')'); + state.Error("Class \"" + info->name + "\" has no static field \"" + String(str, length) + ')'); } return 1; } template - int LuaClass::ToStringProxy(lua_State* state) + int LuaClass::ToStringProxy(lua_State* internalState) { - LuaInstance& lua = *LuaInstance::GetInstance(state); + LuaState state = LuaInstance::GetState(internalState); - std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + std::shared_ptr& info = *static_cast*>(state.ToUserdata(state.GetIndexOfUpValue(1))); - lua.PushString(info->name); + state.PushString(info->name); return 1; } } diff --git a/include/Nazara/Lua/LuaCoroutine.hpp b/include/Nazara/Lua/LuaCoroutine.hpp new file mode 100644 index 000000000..a740f635b --- /dev/null +++ b/include/Nazara/Lua/LuaCoroutine.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Lua scripting module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_LUACOROUTINE_HPP +#define NAZARA_LUACOROUTINE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_LUA_API LuaCoroutine : public LuaState + { + friend class LuaState; + + public: + LuaCoroutine(const LuaCoroutine&) = delete; + inline LuaCoroutine(LuaCoroutine&& instance); + ~LuaCoroutine(); + + bool CanResume() const; + + Ternary Resume(unsigned int argCount = 0); + + LuaCoroutine& operator=(const LuaCoroutine&) = delete; + inline LuaCoroutine& operator=(LuaCoroutine&& instance); + + private: + LuaCoroutine(lua_State* internalState, int refIndex); + + bool Run(int argCount, int resultCount) override; + + int m_ref; + }; +} + +#include + +#endif // NAZARA_LUACOROUTINE_HPP diff --git a/include/Nazara/Lua/LuaCoroutine.inl b/include/Nazara/Lua/LuaCoroutine.inl new file mode 100644 index 000000000..7dcdd0e07 --- /dev/null +++ b/include/Nazara/Lua/LuaCoroutine.inl @@ -0,0 +1,25 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Lua scripting module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline LuaCoroutine::LuaCoroutine(LuaCoroutine&& instance) : + LuaState(std::move(instance)), + m_ref(instance.m_ref) + { + instance.m_ref = -1; + } + + inline LuaCoroutine& LuaCoroutine::operator=(LuaCoroutine&& instance) + { + LuaState::operator=(std::move(instance)); + + m_ref = instance.m_ref; + instance.m_ref = -1; + + return *this; + } +} diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 34a09d11a..93374958b 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -1,201 +1,54 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once -#ifndef NAZARA_LUASTATE_HPP -#define NAZARA_LUASTATE_HPP +#ifndef NAZARA_LUAINSTANCE_HPP +#define NAZARA_LUAINSTANCE_HPP #include -#include -#include -#include -#include -#include +#include #include #include -struct lua_Debug; -struct lua_State; - namespace Nz { - class LuaInstance; - - using LuaCFunction = int (*)(lua_State* state); - using LuaFunction = std::function; - - class NAZARA_LUA_API LuaInstance + class NAZARA_LUA_API LuaInstance : public LuaState { + friend class LuaCoroutine; + friend class LuaState; + public: LuaInstance(); LuaInstance(const LuaInstance&) = delete; - inline LuaInstance(LuaInstance&& instance) noexcept; + LuaInstance(LuaInstance&& instance) = default; ~LuaInstance(); - void ArgCheck(bool condition, unsigned int argNum, const char* error) const; - void ArgCheck(bool condition, unsigned int argNum, const String& error) const; - int ArgError(unsigned int argNum, const char* error) const; - int ArgError(unsigned int argNum, const String& error) const; - - bool Call(unsigned int argCount); - bool Call(unsigned int argCount, unsigned int resultCount); - - 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 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; - 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; - 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; - void CheckStack(int space, const String& error) const; - const char* CheckString(int index, std::size_t* length = nullptr) const; - const char* CheckString(int index, const char* defValue, std::size_t* length = nullptr) const; - void CheckType(int index, LuaType type) const; - void* CheckUserdata(int index, const char* tname) const; - void* CheckUserdata(int index, const String& tname) const; - - bool Compare(int index1, int index2, LuaComparison comparison) const; - void Compute(LuaOperation operation) const; - - void Concatenate(int count) const; - - int CreateReference(); - void DestroyReference(int ref); - - String DumpStack() const; - - void Error(const char* message) const; - void Error(const String& message) const; - - bool Execute(const String& code); - bool ExecuteFromFile(const String& filePath); - bool ExecuteFromMemory(const void* data, std::size_t size); - bool ExecuteFromStream(Stream& stream); - - int GetAbsIndex(int index) 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; - inline lua_State* GetInternalState() const; - inline String GetLastError() const; inline std::size_t GetMemoryLimit() const; inline std::size_t GetMemoryUsage() const; - LuaType GetMetatable(const char* tname) const; - LuaType GetMetatable(const String& tname) const; - bool GetMetatable(int index) const; - unsigned int GetStackTop() const; - LuaType GetTable(int index = -2) const; inline UInt32 GetTimeLimit() const; - LuaType GetType(int index) const; - const char* GetTypeName(LuaType type) const; - void Insert(int index) const; - - bool IsOfType(int index, LuaType type) const; - bool IsOfType(int index, const char* tname) const; - bool IsOfType(int index, const String& tname) const; - bool IsValid(int index) const; - - long long Length(int index) const; - - void MoveTo(LuaInstance* instance, int n) const; - - bool NewMetatable(const char* str); - bool NewMetatable(const String& str); - bool Next(int index = -2) const; - - void Pop(unsigned int n = 1U) const; - - template int Push(T arg) const; - template int Push(T firstArg, T2 secondArg, Args... args) const; - void PushBoolean(bool value) const; - void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0) const; - template void PushField(const char* name, T&& arg, int tableIndex = -2) const; - template void PushField(const String& name, T&& arg, int tableIndex = -2) const; - void PushFunction(LuaFunction func) const; - template void PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const; - template void PushGlobal(const char* name, T&& arg); - template void PushGlobal(const String& name, T&& arg); - template void PushInstance(const char* tname, const T& instance) 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, std::size_t size) const; - void PushString(const String& str) const; - void PushTable(std::size_t sequenceElementCount = 0, std::size_t arrayElementCount = 0) const; - void* PushUserdata(std::size_t size) const; - void PushValue(int index) const; - - void Remove(int index) const; - void Replace(int index) const; - - void SetField(const char* name, int tableIndex = -2) const; - void SetField(const String& name, int tableIndex = -2) const; - void SetGlobal(const char* name); - void SetGlobal(const String& name); - void SetMetatable(const char* tname) const; - void SetMetatable(const String& tname) const; - void SetMetatable(int index) const; - void SetMemoryLimit(std::size_t memoryLimit); - void SetTable(int index = -3) const; - void SetTimeLimit(UInt32 timeLimit); - - bool ToBoolean(int index) const; - long long ToInteger(int index, bool* succeeded = nullptr) const; - double ToNumber(int index, bool* succeeded = nullptr) const; - const void* ToPointer(int index) const; - const char* ToString(int index, std::size_t* length = nullptr) const; - void* ToUserdata(int index) const; - void* ToUserdata(int index, const char* tname) const; - void* ToUserdata(int index, const String& tname) const; + inline void SetMemoryLimit(std::size_t memoryLimit); + inline void SetTimeLimit(UInt32 limit); LuaInstance& operator=(const LuaInstance&) = delete; - inline LuaInstance& operator=(LuaInstance&& instance) noexcept; - - static int GetIndexOfUpValue(int upValue); - static LuaInstance* GetInstance(lua_State* state); + LuaInstance& operator=(LuaInstance&& instance) = default; private: - template T CheckBounds(int index, long long value) const; - bool Run(int argCount, int resultCount); + inline void SetMemoryUsage(std::size_t memoryUsage); static void* MemoryAllocator(void *ud, void *ptr, std::size_t osize, std::size_t nsize); - static int ProxyFunc(lua_State* state); - static void TimeLimiter(lua_State* state, lua_Debug* debug); + static void TimeLimiter(lua_State* internalState, lua_Debug* debug); std::size_t m_memoryLimit; std::size_t m_memoryUsage; UInt32 m_timeLimit; Clock m_clock; - String m_lastError; - lua_State* m_state; unsigned int m_level; }; } #include -#endif // NAZARA_LUASTATE_HPP +#endif // NAZARA_LUAINSTANCE_HPP diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 6c3a4ff7e..59bf8d79e 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -1,41 +1,12 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // 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 -#include -#include +#include namespace Nz { - inline LuaInstance::LuaInstance(LuaInstance&& instance) noexcept : - m_memoryLimit(instance.m_memoryLimit), - m_memoryUsage(instance.m_memoryUsage), - m_timeLimit(instance.m_timeLimit), - m_clock(std::move(instance.m_clock)), - m_lastError(std::move(instance.m_lastError)), - m_state(instance.m_state), - m_level(instance.m_level) - { - instance.m_state = nullptr; - } - - inline lua_State* LuaInstance::GetInternalState() const - { - return m_state; - } - - inline String LuaInstance::GetLastError() const - { - return m_lastError; - } - inline std::size_t LuaInstance::GetMemoryLimit() const { return m_memoryLimit; @@ -51,773 +22,15 @@ namespace Nz return m_timeLimit; } - inline LuaInstance& LuaInstance::operator=(LuaInstance&& instance) noexcept + inline void LuaInstance::SetMemoryLimit(std::size_t memoryLimit) { - m_clock = std::move(instance.m_clock); - m_lastError = std::move(instance.m_lastError); - m_level = instance.m_level; - m_memoryLimit = instance.m_memoryLimit; - m_memoryUsage = instance.m_memoryUsage; - m_state = instance.m_state; - m_timeLimit = instance.m_timeLimit; - - instance.m_state = nullptr; - - return *this; + m_memoryLimit = memoryLimit; } - // Functions args - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, bool* arg, TypeTag) + inline void LuaInstance::SetTimeLimit(UInt32 limit) { - *arg = instance.CheckBoolean(index); - return 1; - } - - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, bool* arg, bool defValue, TypeTag) - { - *arg = instance.CheckBoolean(index, defValue); - return 1; - } - - 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); - - arg->assign(str, strLength); - - return 1; - } - - inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, String* arg, TypeTag) - { - std::size_t strLength = 0; - const char* str = instance.CheckString(index, &strLength); - - arg->Set(str, strLength); - - return 1; - } - - template - std::enable_if_t::value && !EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) - { - using UnderlyingT = std::underlying_type_t; - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); - } - - template - std::enable_if_t::value && !EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - using UnderlyingT = std::underlying_type_t; - return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); - } - - template - std::enable_if_t::value && EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) - { - using UnderlyingT = std::underlying_type_t; - - UnderlyingT pot2Val; - unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, TypeTag()); - - *arg = static_cast(IntegralLog2Pot(pot2Val)); - return ret; - } - - template - std::enable_if_t::value && EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - using UnderlyingT = std::underlying_type_t; - - UnderlyingT pot2Val; - unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, 1U << static_cast(defValue), TypeTag()); - - *arg = static_cast(IntegralLog2Pot(pot2Val)); - return ret; - } - - template - unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Flags* arg, TypeTag>) - { - *arg = Flags(instance.CheckBoundInteger(index)); - 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, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) - { - *arg = instance.CheckBoundInteger(index); - return 1; - } - - template - std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag) - { - *arg = instance.CheckBoundInteger(index, defValue); - return 1; - } - - template - 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); - else - { - *arg = defValue; - return 1; - } - } - - template - unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag) - { - return LuaImplQueryArg(instance, index, arg, TypeTag()); - } - - template - 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(const LuaInstance& instance, bool val, TypeTag) - { - instance.PushBoolean(val); - return 1; - } - - inline int LuaImplReplyVal(const LuaInstance& instance, double val, TypeTag) - { - instance.PushNumber(val); - return 1; - } - - inline int LuaImplReplyVal(const LuaInstance& instance, float val, TypeTag) - { - instance.PushNumber(val); - return 1; - } - - template - std::enable_if_t::value && !EnumAsFlags::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - using EnumT = typename std::underlying_type::type; - return LuaImplReplyVal(instance, static_cast(val), TypeTag()); - } - - template - std::enable_if_t::value && EnumAsFlags::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - Flags flags(val); - return LuaImplReplyVal(instance, flags, TypeTag()); - } - - template - int LuaImplReplyVal(const LuaInstance& instance, Flags val, TypeTag>) - { - instance.PushInteger(UInt32(val)); - return 1; - } - - template - std::enable_if_t::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - instance.PushInteger(val); - return 1; - } - - template - std::enable_if_t::value || std::is_enum::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - return LuaImplReplyVal(instance, val, TypeTag()); - } - - template - std::enable_if_t::value || std::is_enum::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - return LuaImplReplyVal(instance, val, TypeTag()); - } - - template - std::enable_if_t::value && !std::is_enum::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - return LuaImplReplyVal(instance, std::move(val), TypeTag()); - } - - template - std::enable_if_t::value && !std::is_enum::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag) - { - return LuaImplReplyVal(instance, std::move(val), TypeTag()); - } - - template - int LuaImplReplyVal(const LuaInstance& instance, T&& val, TypeTag) - { - return LuaImplReplyVal(instance, std::forward(val), TypeTag()); - } - - inline int LuaImplReplyVal(const LuaInstance& instance, std::string&& val, TypeTag) - { - instance.PushString(val.c_str(), val.size()); - return 1; - } - - template - inline int LuaImplReplyVal(const LuaInstance& instance, std::vector&& valContainer, TypeTag>) - { - std::size_t index = 1; - instance.PushTable(valContainer.size()); - for (T& val : valContainer) - { - instance.PushInteger(index++); - if (LuaImplReplyVal(instance, std::move(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()); - return 1; - } - - inline int LuaImplReplyVal(const LuaInstance& instance, String&& val, TypeTag) - { - instance.PushString(std::move(val)); - return 1; - } - - template - int LuaImplReplyVal(const LuaInstance& instance, std::pair&& val, TypeTag>) - { - int retVal = 0; - - retVal += LuaImplReplyVal(instance, std::move(val.first), TypeTag()); - retVal += LuaImplReplyVal(instance, std::move(val.second), TypeTag()); - - return retVal; - } - - template - struct LuaImplArgProcesser; - - template<> - struct LuaImplArgProcesser - { - template - static unsigned int Process(const LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) - { - return LuaImplQueryArg(instance, argIndex, &std::get(args), std::get() - N - 1>(defArgs), TypeTag()); - } - }; - - template<> - struct LuaImplArgProcesser - { - template - static unsigned int Process(const LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) - { - NazaraUnused(defArgs); - - return LuaImplQueryArg(instance, argIndex, &std::get(args), TypeTag()); - } - }; - - template - class LuaImplFunctionProxy - { - public: - template - class Impl - { - static constexpr std::size_t ArgCount = sizeof...(Args); - static constexpr std::size_t DefArgCount = sizeof...(DefArgs); - - static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument"); - - static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; - - public: - Impl(DefArgs... defArgs) : - m_defaultArgs(std::forward(defArgs)...) - { - } - - void ProcessArguments(const LuaInstance& instance) const - { - m_index = 1; - ProcessArgs<0, Args...>(instance); - } - - int Invoke(const LuaInstance& instance, void(*func)(Args...)) const - { - NazaraUnused(instance); - - Apply(func, m_args); - return 0; - } - - template - int Invoke(const LuaInstance& instance, Ret(*func)(Args...)) const - { - return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag()); - } - - private: - using ArgContainer = std::tuple>...>; - using DefArgContainer = std::tuple>...>; - - template - void ProcessArgs(const LuaInstance& instance) const - { - NazaraUnused(instance); - - // No argument to process - } - - template - void ProcessArgs(const LuaInstance& instance) const - { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); - } - - template - void ProcessArgs(const LuaInstance& instance) const - { - ProcessArgs(instance); - ProcessArgs(instance); - } - - mutable ArgContainer m_args; - DefArgContainer m_defaultArgs; - mutable unsigned int m_index; - }; - }; - - template - class LuaImplMethodProxy - { - public: - template - class Impl - { - static constexpr std::size_t ArgCount = sizeof...(Args); - static constexpr std::size_t DefArgCount = sizeof...(DefArgs); - - static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument"); - - static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; - - public: - Impl(DefArgs... defArgs) : - m_defaultArgs(std::forward(defArgs)...) - { - } - - void ProcessArguments(const LuaInstance& instance) const - { - m_index = 2; //< 1 being the instance - ProcessArgs<0, Args...>(instance); - } - - template - std::enable_if_t::value, int> Invoke(const LuaInstance& instance, T& object, void(P::*func)(Args...)) const - { - NazaraUnused(instance); - - Apply(object, func, m_args); - return 0; - } - - template - 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(const LuaInstance& instance, T& object, T&(P::*func)(Args...)) const - { - T& r = Apply(object, func, m_args); - if (&r == &object) - { - instance.PushValue(1); //< Userdata - return 1; - } - else - return LuaImplReplyVal(instance, r, TypeTag()); - } - - template - std::enable_if_t::value, int> Invoke(const LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const - { - NazaraUnused(instance); - - Apply(object, func, m_args); - return 0; - } - - template - 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::value, int> Invoke(const LuaInstance& instance, const T& object, const T&(P::*func)(Args...) const) const - { - const T& r = Apply(object, func, m_args); - if (&r == &object) - { - instance.PushValue(1); //< Userdata - return 1; - } - else - return LuaImplReplyVal(instance, r, TypeTag()); - } - - template - std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, T& object, void(P::*func)(Args...)) const - { - if (!object) - { - instance.Error("Invalid object"); - return 0; - } - - Apply(*object, func, m_args); - return 0; - } - - 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()); - } - - template - std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, T& object, typename PointedType::type&(P::*func)(Args...) const) const - { - if (!object) - { - instance.Error("Invalid object"); - return 0; - } - - const typename PointedType::type& r = Apply(*object, func, m_args); - if (&r == &*object) - { - instance.PushValue(1); //< Userdata - return 1; - } - else - return LuaImplReplyVal(instance, r, TypeTag()); - } - - template - std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const - { - if (!object) - { - instance.Error("Invalid object"); - return 0; - } - - Apply(*object, func, m_args); - return 0; - } - - 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()); - } - - template - std::enable_if_t::type>::value, int> Invoke(const LuaInstance& instance, const T& object, const typename PointedType::type&(P::*func)(Args...) const) const - { - if (!object) - { - instance.Error("Invalid object"); - return 0; - } - - const typename PointedType::type& r = Apply(*object, func, m_args); - if (&r == &*object) - { - instance.PushValue(1); //< Userdata - return 1; - } - else - return LuaImplReplyVal(instance, r, TypeTag()); - } - - private: - using ArgContainer = std::tuple>...>; - using DefArgContainer = std::tuple>...>; - - template - void ProcessArgs(const LuaInstance& instance) const - { - NazaraUnused(instance); - - // No argument to process - } - - template - void ProcessArgs(const LuaInstance& instance) const - { - m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); - } - - template - void ProcessArgs(const LuaInstance& instance) const - { - ProcessArgs(instance); - ProcessArgs(instance); - } - - mutable ArgContainer m_args; - DefArgContainer m_defaultArgs; - mutable unsigned int m_index; - }; - }; - - template - T LuaInstance::Check(int* index) const - { - NazaraAssert(index, "Invalid index pointer"); - - T object; - *index += LuaImplQueryArg(*this, *index, &object, TypeTag()); - - return object; - } - - template - T LuaInstance::Check(int* index, T defValue) const - { - NazaraAssert(index, "Invalid index pointer"); - - T object; - *index += LuaImplQueryArg(*this, *index, &object, defValue, TypeTag()); - - 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 - { - T object; - - GetField(fieldName, tableIndex); - tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag()); - Pop(); - - return object; - } - - template - T LuaInstance::CheckField(const String& fieldName, int tableIndex) const - { - return CheckField(fieldName.GetConstBuffer(), tableIndex); - } - - template - T LuaInstance::CheckField(const char* fieldName, T defValue, int tableIndex) const - { - 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) const - { - return CheckField(fieldName.GetConstBuffer(), defValue, tableIndex); - } - - template - T LuaInstance::CheckGlobal(const char* fieldName) const - { - T object; - - GetGlobal(fieldName); - LuaImplQueryArg(*this, -1, &object, TypeTag()); - Pop(); - - return object; - } - - template - T LuaInstance::CheckGlobal(const String& fieldName) const - { - return CheckGlobal(fieldName.GetConstBuffer()); - } - - template - T LuaInstance::CheckGlobal(const char* fieldName, T defValue) const - { - T object; - - GetGlobal(fieldName); - LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); - Pop(); - - return object; - } - - template - T LuaInstance::CheckGlobal(const String& fieldName, T defValue) const - { - return CheckGlobal(fieldName.GetConstBuffer(), defValue); - } - - template - int LuaInstance::Push(T arg) const - { - return LuaImplReplyVal(*this, std::move(arg), TypeTag()); - } - - template - int LuaInstance::Push(T firstArg, T2 secondArg, Args... args) const - { - int valCount = 0; - valCount += Push(std::move(firstArg)); - valCount += Push(secondArg, std::forward(args)...); - - return valCount; - } - - template - void LuaInstance::PushField(const char* name, T&& arg, int tableIndex) const - { - Push(std::forward(arg)); - SetField(name, tableIndex); - } - - template - void LuaInstance::PushField(const String& name, T&& arg, int tableIndex) const - { - PushField(name.GetConstBuffer(), std::forward(arg), tableIndex); - } - - template - void LuaInstance::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const - { - typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - - PushFunction([func, handler] (LuaInstance& lua) -> int - { - handler.ProcessArguments(lua); - - return handler.Invoke(lua, func); - }); - } - - template - void LuaInstance::PushGlobal(const char* name, T&& arg) - { - Push(std::forward(arg)); - SetGlobal(name); - } - - template - void LuaInstance::PushGlobal(const String& name, T&& arg) - { - PushGlobal(name.GetConstBuffer(), std::forward(arg)); - } - - template - void LuaInstance::PushInstance(const char* tname, const T& instance) const - { - T* userdata = static_cast(PushUserdata(sizeof(T))); - PlacementNew(userdata, instance); - - SetMetatable(tname); - } - - template - void LuaInstance::PushInstance(const char* tname, T&& instance) const - { - T* userdata = static_cast(PushUserdata(sizeof(T))); - PlacementNew(userdata, std::move(instance)); - - SetMetatable(tname); - } - - template - void LuaInstance::PushInstance(const char* tname, Args&&... args) const - { - T* userdata = static_cast(PushUserdata(sizeof(T))); - PlacementNew(userdata, std::forward(args)...); - - SetMetatable(tname); - } - - template - T LuaInstance::CheckBounds(int index, long long value) const - { - constexpr long long minBounds = std::numeric_limits::min(); - constexpr 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); + m_timeLimit = limit; } } + +#include diff --git a/include/Nazara/Lua/LuaState.hpp b/include/Nazara/Lua/LuaState.hpp new file mode 100644 index 000000000..fe34d794a --- /dev/null +++ b/include/Nazara/Lua/LuaState.hpp @@ -0,0 +1,199 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Lua scripting module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_LUASTATE_HPP +#define NAZARA_LUASTATE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct lua_Debug; +struct lua_State; + +namespace Nz +{ + class LuaCoroutine; + class LuaInstance; + class LuaState; + + using LuaCFunction = int (*)(lua_State* internalState); + using LuaFunction = std::function; + + class NAZARA_LUA_API LuaState + { + public: + LuaState(const LuaState&) = default; + LuaState(LuaState&& instance) noexcept; + ~LuaState() = default; + + void ArgCheck(bool condition, unsigned int argNum, const char* error) const; + void ArgCheck(bool condition, unsigned int argNum, const String& error) const; + int ArgError(unsigned int argNum, const char* error) const; + int ArgError(unsigned int argNum, const String& error) const; + + bool Call(unsigned int argCount); + bool Call(unsigned int argCount, unsigned int resultCount); + + 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 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; + 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; + 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; + void CheckStack(int space, const String& error) const; + const char* CheckString(int index, std::size_t* length = nullptr) const; + const char* CheckString(int index, const char* defValue, std::size_t* length = nullptr) const; + void CheckType(int index, LuaType type) const; + void* CheckUserdata(int index, const char* tname) const; + void* CheckUserdata(int index, const String& tname) const; + + bool Compare(int index1, int index2, LuaComparison comparison) const; + void Compute(LuaOperation operation) const; + + void Concatenate(int count) const; + + int CreateReference(); + void DestroyReference(int ref); + + String DumpStack() const; + + void Error(const char* message) const; + void Error(const String& message) const; + + bool Execute(const String& code); + bool ExecuteFromFile(const String& filePath); + bool ExecuteFromMemory(const void* data, std::size_t size); + bool ExecuteFromStream(Stream& stream); + + int GetAbsIndex(int index) 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; + inline lua_State* GetInternalState() const; + inline String GetLastError() const; + LuaType GetMetatable(const char* tname) const; + LuaType GetMetatable(const String& tname) const; + bool GetMetatable(int index) const; + unsigned int GetStackTop() const; + LuaType GetTable(int index = -2) const; + LuaType GetTableRaw(int index = -2) const; + LuaType GetType(int index) const; + const char* GetTypeName(LuaType type) const; + + void Insert(int index) const; + + bool IsOfType(int index, LuaType type) const; + bool IsOfType(int index, const char* tname) const; + bool IsOfType(int index, const String& tname) const; + bool IsValid(int index) const; + + long long Length(int index) const; + std::size_t LengthRaw(int index) const; + + void MoveTo(LuaState* instance, int n) const; + + LuaCoroutine NewCoroutine(); + bool NewMetatable(const char* str); + bool NewMetatable(const String& str); + bool Next(int index = -2) const; + + void Pop(unsigned int n = 1U) const; + + template int Push(T arg) const; + template int Push(T firstArg, T2 secondArg, Args... args) const; + void PushBoolean(bool value) const; + void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0) const; + template void PushField(const char* name, T&& arg, int tableIndex = -2) const; + template void PushField(const String& name, T&& arg, int tableIndex = -2) const; + void PushFunction(LuaFunction func) const; + template void PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const; + template void PushGlobal(const char* name, T&& arg); + template void PushGlobal(const String& name, T&& arg); + template void PushInstance(const char* tname, const T& instance) 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, std::size_t size) const; + void PushString(const String& str) const; + void PushTable(std::size_t sequenceElementCount = 0, std::size_t arrayElementCount = 0) const; + void* PushUserdata(std::size_t size) const; + void PushValue(int index) const; + + void Remove(int index) const; + void Replace(int index) const; + + void SetField(const char* name, int tableIndex = -2) const; + void SetField(const String& name, int tableIndex = -2) const; + void SetGlobal(const char* name); + void SetGlobal(const String& name); + void SetMetatable(const char* tname) const; + void SetMetatable(const String& tname) const; + void SetMetatable(int index) const; + void SetTable(int index = -3) const; + void SetTableRaw(int index = -3) const; + + bool ToBoolean(int index) const; + long long ToInteger(int index, bool* succeeded = nullptr) const; + double ToNumber(int index, bool* succeeded = nullptr) const; + const void* ToPointer(int index) const; + const char* ToString(int index, std::size_t* length = nullptr) const; + void* ToUserdata(int index) const; + void* ToUserdata(int index, const char* tname) const; + void* ToUserdata(int index, const String& tname) const; + + LuaState& operator=(const LuaState&) = default; + LuaState& operator=(LuaState&& instance) noexcept; + + static int GetIndexOfUpValue(int upValue); + static LuaInstance& GetInstance(lua_State* internalState); + static inline LuaState GetState(lua_State* internalState); + + protected: + LuaState(lua_State* internalState); + + template std::enable_if_t::value, T> CheckBounds(int index, long long value) const; + template std::enable_if_t::value, T> CheckBounds(int index, long long value) const; + virtual bool Run(int argCount, int resultCount); + + static int ProxyFunc(lua_State* internalState); + + String m_lastError; + lua_State* m_state; + }; +} + +#include + +#endif // NAZARA_LUASTATE_HPP diff --git a/include/Nazara/Lua/LuaState.inl b/include/Nazara/Lua/LuaState.inl new file mode 100644 index 000000000..da191d8a2 --- /dev/null +++ b/include/Nazara/Lua/LuaState.inl @@ -0,0 +1,807 @@ +// Copyright (C) 2017 Jérôme Leclercq +// 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 +#include +#include +#include + +namespace Nz +{ + inline LuaState::LuaState(lua_State* internalState) : + m_state(internalState) + { + } + + inline lua_State* LuaState::GetInternalState() const + { + return m_state; + } + + inline String LuaState::GetLastError() const + { + return m_lastError; + } + + // Functions args + inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, bool* arg, TypeTag) + { + *arg = instance.CheckBoolean(index); + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, bool* arg, bool defValue, TypeTag) + { + *arg = instance.CheckBoolean(index, defValue); + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, std::string* arg, TypeTag) + { + std::size_t strLength = 0; + const char* str = instance.CheckString(index, &strLength); + + arg->assign(str, strLength); + + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, String* arg, TypeTag) + { + std::size_t strLength = 0; + const char* str = instance.CheckString(index, &strLength); + + arg->Set(str, strLength); + + return 1; + } + + template + std::enable_if_t::value && !EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); + } + + template + std::enable_if_t::value && !EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); + } + + template + std::enable_if_t::value && EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + + UnderlyingT pot2Val; + unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, TypeTag()); + + *arg = static_cast(IntegralLog2Pot(pot2Val)); + return ret; + } + + template + std::enable_if_t::value && EnumAsFlags::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) + { + using UnderlyingT = std::underlying_type_t; + + UnderlyingT pot2Val; + unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, 1U << static_cast(defValue), TypeTag()); + + *arg = static_cast(IntegralLog2Pot(pot2Val)); + return ret; + } + + template + unsigned int LuaImplQueryArg(const LuaState& instance, int index, Flags* arg, TypeTag>) + { + *arg = Flags(instance.CheckBoundInteger(index)); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + { + *arg = static_cast(instance.CheckNumber(index)); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaState& 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, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + { + *arg = instance.CheckBoundInteger(index); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = instance.CheckBoundInteger(index, defValue); + return 1; + } + + template + std::enable_if_t::value && !std::is_enum::value && !std::is_floating_point::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, const T& defValue, TypeTag tag) + { + if (instance.IsValid(index)) + return LuaImplQueryArg(instance, index, arg, tag); + else + { + *arg = defValue; + return 1; + } + } + + template + unsigned int LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag) + { + return LuaImplQueryArg(instance, index, arg, TypeTag()); + } + + template + unsigned int LuaImplQueryArg(const LuaState& instance, int index, T* arg, const T& defValue, TypeTag) + { + return LuaImplQueryArg(instance, index, arg, defValue, TypeTag()); + } + + // Function returns + inline int LuaImplReplyVal(const LuaState& instance, bool val, TypeTag) + { + instance.PushBoolean(val); + return 1; + } + + inline int LuaImplReplyVal(const LuaState& instance, double val, TypeTag) + { + instance.PushNumber(val); + return 1; + } + + inline int LuaImplReplyVal(const LuaState& instance, float val, TypeTag) + { + instance.PushNumber(val); + return 1; + } + + template + std::enable_if_t::value && !EnumAsFlags::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + using EnumT = typename std::underlying_type::type; + return LuaImplReplyVal(instance, static_cast(val), TypeTag()); + } + + template + std::enable_if_t::value && EnumAsFlags::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + Flags flags(val); + return LuaImplReplyVal(instance, flags, TypeTag()); + } + + template + int LuaImplReplyVal(const LuaState& instance, Flags val, TypeTag>) + { + instance.PushInteger(UInt32(val)); + return 1; + } + + template + std::enable_if_t::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + instance.PushInteger(val); + return 1; + } + + template + std::enable_if_t::value || std::is_enum::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + return LuaImplReplyVal(instance, val, TypeTag()); + } + + template + std::enable_if_t::value || std::is_enum::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + return LuaImplReplyVal(instance, val, TypeTag()); + } + + template + std::enable_if_t::value && !std::is_enum::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + return LuaImplReplyVal(instance, std::move(val), TypeTag()); + } + + template + std::enable_if_t::value && !std::is_enum::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag) + { + return LuaImplReplyVal(instance, std::move(val), TypeTag()); + } + + template + int LuaImplReplyVal(const LuaState& instance, T&& val, TypeTag) + { + return LuaImplReplyVal(instance, std::forward(val), TypeTag()); + } + + inline int LuaImplReplyVal(const LuaState& instance, std::string&& val, TypeTag) + { + instance.PushString(val.c_str(), val.size()); + return 1; + } + + template + inline int LuaImplReplyVal(const LuaState& instance, std::vector&& valContainer, TypeTag>) + { + std::size_t index = 1; + instance.PushTable(valContainer.size()); + for (T& val : valContainer) + { + instance.PushInteger(index++); + if (LuaImplReplyVal(instance, std::move(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 LuaState& instance, ByteArray&& val, TypeTag) + { + instance.PushString(reinterpret_cast(val.GetConstBuffer()), val.GetSize()); + return 1; + } + + inline int LuaImplReplyVal(const LuaState& instance, String&& val, TypeTag) + { + instance.PushString(std::move(val)); + return 1; + } + + template + int LuaImplReplyVal(const LuaState& instance, std::pair&& val, TypeTag>) + { + int retVal = 0; + + retVal += LuaImplReplyVal(instance, std::move(val.first), TypeTag()); + retVal += LuaImplReplyVal(instance, std::move(val.second), TypeTag()); + + return retVal; + } + + template + struct LuaImplArgProcesser; + + template<> + struct LuaImplArgProcesser + { + template + static unsigned int Process(const LuaState& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) + { + return LuaImplQueryArg(instance, argIndex, &std::get(args), std::get() - N - 1>(defArgs), TypeTag()); + } + }; + + template<> + struct LuaImplArgProcesser + { + template + static unsigned int Process(const LuaState& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) + { + NazaraUnused(defArgs); + + return LuaImplQueryArg(instance, argIndex, &std::get(args), TypeTag()); + } + }; + + template + class LuaImplFunctionProxy + { + public: + template + class Impl + { + static constexpr std::size_t ArgCount = sizeof...(Args); + static constexpr std::size_t DefArgCount = sizeof...(DefArgs); + + static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument"); + + static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; + + public: + Impl(DefArgs... defArgs) : + m_defaultArgs(std::forward(defArgs)...) + { + } + + void ProcessArguments(const LuaState& instance) const + { + m_index = 1; + ProcessArgs<0, Args...>(instance); + } + + int Invoke(const LuaState& instance, void(*func)(Args...)) const + { + NazaraUnused(instance); + + Apply(func, m_args); + return 0; + } + + template + int Invoke(const LuaState& instance, Ret(*func)(Args...)) const + { + return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag()); + } + + private: + using ArgContainer = std::tuple>...>; + using DefArgContainer = std::tuple>...>; + + template + void ProcessArgs(const LuaState& instance) const + { + NazaraUnused(instance); + + // No argument to process + } + + template + void ProcessArgs(const LuaState& instance) const + { + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); + } + + template + void ProcessArgs(const LuaState& instance) const + { + ProcessArgs(instance); + ProcessArgs(instance); + } + + mutable ArgContainer m_args; + DefArgContainer m_defaultArgs; + mutable unsigned int m_index; + }; + }; + + template + class LuaImplMethodProxy + { + public: + template + class Impl + { + static constexpr std::size_t ArgCount = sizeof...(Args); + static constexpr std::size_t DefArgCount = sizeof...(DefArgs); + + static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument"); + + static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; + + public: + Impl(DefArgs... defArgs) : + m_defaultArgs(std::forward(defArgs)...) + { + } + + void ProcessArguments(const LuaState& instance) const + { + m_index = 2; //< 1 being the instance + ProcessArgs<0, Args...>(instance); + } + + template + std::enable_if_t::value, int> Invoke(const LuaState& instance, T& object, void(P::*func)(Args...)) const + { + NazaraUnused(instance); + + Apply(object, func, m_args); + return 0; + } + + template + std::enable_if_t::value, int> Invoke(const LuaState& 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(const LuaState& instance, T& object, T&(P::*func)(Args...)) const + { + T& r = Apply(object, func, m_args); + if (&r == &object) + { + instance.PushValue(1); //< Userdata + return 1; + } + else + return LuaImplReplyVal(instance, r, TypeTag()); + } + + template + std::enable_if_t::value, int> Invoke(const LuaState& instance, const T& object, void(P::*func)(Args...) const) const + { + NazaraUnused(instance); + + Apply(object, func, m_args); + return 0; + } + + template + std::enable_if_t::value, int> Invoke(const LuaState& 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::value, int> Invoke(const LuaState& instance, const T& object, const T&(P::*func)(Args...) const) const + { + const T& r = Apply(object, func, m_args); + if (&r == &object) + { + instance.PushValue(1); //< Userdata + return 1; + } + else + return LuaImplReplyVal(instance, r, TypeTag()); + } + + template + std::enable_if_t::type>::value, int> Invoke(const LuaState& instance, T& object, void(P::*func)(Args...)) const + { + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + + Apply(*object, func, m_args); + return 0; + } + + template + std::enable_if_t::type>::value, int> Invoke(const LuaState& 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()); + } + + template + std::enable_if_t::type>::value, int> Invoke(const LuaState& instance, T& object, typename PointedType::type&(P::*func)(Args...) const) const + { + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + + const typename PointedType::type& r = Apply(*object, func, m_args); + if (&r == &*object) + { + instance.PushValue(1); //< Userdata + return 1; + } + else + return LuaImplReplyVal(instance, r, TypeTag()); + } + + template + std::enable_if_t::type>::value, int> Invoke(const LuaState& instance, const T& object, void(P::*func)(Args...) const) const + { + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + + Apply(*object, func, m_args); + return 0; + } + + template + std::enable_if_t::type>::value, int> Invoke(const LuaState& 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()); + } + + template + std::enable_if_t::type>::value, int> Invoke(const LuaState& instance, const T& object, const typename PointedType::type&(P::*func)(Args...) const) const + { + if (!object) + { + instance.Error("Invalid object"); + return 0; + } + + const typename PointedType::type& r = Apply(*object, func, m_args); + if (&r == &*object) + { + instance.PushValue(1); //< Userdata + return 1; + } + else + return LuaImplReplyVal(instance, r, TypeTag()); + } + + private: + using ArgContainer = std::tuple>...>; + using DefArgContainer = std::tuple>...>; + + template + void ProcessArgs(const LuaState& instance) const + { + NazaraUnused(instance); + + // No argument to process + } + + template + void ProcessArgs(const LuaState& instance) const + { + m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); + } + + template + void ProcessArgs(const LuaState& instance) const + { + ProcessArgs(instance); + ProcessArgs(instance); + } + + mutable ArgContainer m_args; + DefArgContainer m_defaultArgs; + mutable unsigned int m_index; + }; + }; + + template + T LuaState::Check(int* index) const + { + NazaraAssert(index, "Invalid index pointer"); + + T object; + *index += LuaImplQueryArg(*this, *index, &object, TypeTag()); + + return object; + } + + template + T LuaState::Check(int* index, T defValue) const + { + NazaraAssert(index, "Invalid index pointer"); + + T object; + *index += LuaImplQueryArg(*this, *index, &object, defValue, TypeTag()); + + return object; + } + + template + inline T LuaState::CheckBoundInteger(int index) const + { + return CheckBounds(index, CheckInteger(index)); + } + + template + inline T LuaState::CheckBoundInteger(int index, T defValue) const + { + return CheckBounds(index, CheckInteger(index, defValue)); + } + + template + T LuaState::CheckField(const char* fieldName, int tableIndex) const + { + T object; + + GetField(fieldName, tableIndex); + tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag()); + Pop(); + + return object; + } + + template + T LuaState::CheckField(const String& fieldName, int tableIndex) const + { + return CheckField(fieldName.GetConstBuffer(), tableIndex); + } + + template + T LuaState::CheckField(const char* fieldName, T defValue, int tableIndex) const + { + T object; + + GetField(fieldName, tableIndex); + tableIndex += LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); + Pop(); + + return object; + } + + template + T LuaState::CheckField(const String& fieldName, T defValue, int tableIndex) const + { + return CheckField(fieldName.GetConstBuffer(), defValue, tableIndex); + } + + template + T LuaState::CheckGlobal(const char* fieldName) const + { + T object; + + GetGlobal(fieldName); + LuaImplQueryArg(*this, -1, &object, TypeTag()); + Pop(); + + return object; + } + + template + T LuaState::CheckGlobal(const String& fieldName) const + { + return CheckGlobal(fieldName.GetConstBuffer()); + } + + template + T LuaState::CheckGlobal(const char* fieldName, T defValue) const + { + T object; + + GetGlobal(fieldName); + LuaImplQueryArg(*this, -1, &object, defValue, TypeTag()); + Pop(); + + return object; + } + + template + T LuaState::CheckGlobal(const String& fieldName, T defValue) const + { + return CheckGlobal(fieldName.GetConstBuffer(), defValue); + } + + template + int LuaState::Push(T arg) const + { + return LuaImplReplyVal(*this, std::move(arg), TypeTag()); + } + + template + int LuaState::Push(T firstArg, T2 secondArg, Args... args) const + { + int valCount = 0; + valCount += Push(std::move(firstArg)); + valCount += Push(secondArg, std::forward(args)...); + + return valCount; + } + + template + void LuaState::PushField(const char* name, T&& arg, int tableIndex) const + { + Push(std::forward(arg)); + SetField(name, tableIndex); + } + + template + void LuaState::PushField(const String& name, T&& arg, int tableIndex) const + { + PushField(name.GetConstBuffer(), std::forward(arg), tableIndex); + } + + template + void LuaState::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const + { + typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); + + PushFunction([func, handler] (LuaState& lua) -> int + { + handler.ProcessArguments(lua); + + return handler.Invoke(lua, func); + }); + } + + template + void LuaState::PushGlobal(const char* name, T&& arg) + { + Push(std::forward(arg)); + SetGlobal(name); + } + + template + void LuaState::PushGlobal(const String& name, T&& arg) + { + PushGlobal(name.GetConstBuffer(), std::forward(arg)); + } + + template + void LuaState::PushInstance(const char* tname, const T& instance) const + { + T* userdata = static_cast(PushUserdata(sizeof(T))); + PlacementNew(userdata, instance); + + SetMetatable(tname); + } + + template + void LuaState::PushInstance(const char* tname, T&& instance) const + { + T* userdata = static_cast(PushUserdata(sizeof(T))); + PlacementNew(userdata, std::move(instance)); + + SetMetatable(tname); + } + + template + void LuaState::PushInstance(const char* tname, Args&&... args) const + { + T* userdata = static_cast(PushUserdata(sizeof(T))); + PlacementNew(userdata, std::forward(args)...); + + SetMetatable(tname); + } + + template + std::enable_if_t::value, T> LuaState::CheckBounds(int index, long long value) const + { + constexpr long long minBounds = std::numeric_limits::min(); + constexpr 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); + } + + template + std::enable_if_t::value, T> LuaState::CheckBounds(int index, long long value) const + { + constexpr unsigned long long minBounds = 0; + constexpr unsigned 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); + } + + inline LuaState LuaState::GetState(lua_State* internalState) + { + return LuaState(internalState); + } +} diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index f138a8fc9..5ffbe8106 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -1,5 +1,5 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -53,7 +53,7 @@ namespace Nz 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*/ T IntegralPow(T 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); diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 02ede739a..e50385c78 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -97,6 +97,30 @@ namespace Nz return 0; } + + template /*constexpr*/ std::enable_if_t::value, bool> NumberEquals(T a, T b, T maxDifference) + { + T diff = std::abs(a - b); + return diff <= maxDifference; + } + + template /*constexpr*/ std::enable_if_t::value || (!std::is_integral::value && !std::is_floating_point::value), bool> NumberEquals(T a, T b, T maxDifference) + { + if (b > a) + std::swap(a, b); + + T diff = a - b; + return diff <= maxDifference; + } + + template /*constexpr*/ std::enable_if_t::value && std::is_integral::value, bool> NumberEquals(T a, T b, T maxDifference) + { + if (b > a) + std::swap(a, b); + + using UnsignedT = std::make_unsigned_t; + return static_cast(a) - static_cast(b) <= static_cast(maxDifference); + } } /*! @@ -436,9 +460,10 @@ namespace Nz */ //TODO: Mark as constexpr when supported by all major compilers - /*constexpr*/ inline unsigned int IntegralPow(unsigned int base, unsigned int exponent) + template + /*constexpr*/ T IntegralPow(T base, unsigned int exponent) { - unsigned int r = 1; + T r = 1; for (unsigned int i = 0; i < exponent; ++i) r *= base; @@ -463,7 +488,7 @@ namespace Nz template constexpr T Lerp(const T& from, const T& to, const T2& interpolation) { - return from + interpolation * (to - from); + return static_cast(from + interpolation * (to - from)); } /*! @@ -564,11 +589,7 @@ namespace Nz //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); - - T diff = a - b; - return diff <= maxDifference; + return Detail::NumberEquals(a, b, maxDifference); } /*! diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index 6c863b729..b5c4e8b9e 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index a1efd8364..d2dee79f8 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) 2017 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 diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index 25e9a8069..9434cda27 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -74,8 +74,8 @@ namespace Nz Box& Transform(const Matrix4& matrix, bool applyTranslation = true); Box& Translate(const Vector3& translation); - T& operator[](unsigned int i); - T operator[](unsigned int i) const; + T& operator[](std::size_t i); + T operator[](std::size_t i) const; Box operator*(T scalar) const; Box operator*(const Vector3& vec) const; diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 71c98a70b..60275b206 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -133,9 +133,9 @@ namespace Nz 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; } /*! @@ -735,24 +735,15 @@ namespace Nz * \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 + * \remark Access to index greater than 6 is undefined behavior + * \remark Produce a NazaraError if you try to access to index greater 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) + T& Box::operator[](std::size_t i) { - #if NAZARA_MATH_SAFE - if (i >= 6) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 6)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 6, "Index out of range"); return *(&x+i); } @@ -761,24 +752,15 @@ namespace Nz * \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 + * \remark Access to index greater than 6 is undefined behavior + * \remark Produce a NazaraError if you try to access to index greater 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 + T Box::operator[](std::size_t i) const { - #if NAZARA_MATH_SAFE - if (i >= 6) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 6)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 6, "Index out of range"); return *(&x+i); } diff --git a/include/Nazara/Math/Enums.hpp b/include/Nazara/Math/Enums.hpp index 76649906f..0430df83a 100644 --- a/include/Nazara/Math/Enums.hpp +++ b/include/Nazara/Math/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index ab267e81f..b55adc4dd 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index 3b12e7abe..d903de52a 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index 96c78004c..26242caef 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 71f385cac..f459a0526 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 91927d68a..c90439de4 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index f045ac28a..f3effcc5e 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) 2017 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 diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 2b806e56b..dfd8f6b28 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index 3320dce1a..674e8bdb0 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index 0eb201123..0970b5a6d 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) 2017 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 diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 625abe3e4..15bf8cae7 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index bbb313bd5..27adb8b36 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2017 Rémi Bèges - 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 diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index f7f7c693c..def663ee4 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2017 Rémi Bèges - 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 diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index 7e8c0790a..01e86afaf 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Gawaboumga (https://github.com/Gawaboumga) - Jérôme Leclercq +// Copyright (C) 2017 Gawaboumga (https://github.com/Gawaboumga) - 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 diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 6045615ed..2149af8b7 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Gawaboumga (https://github.com/Gawaboumga) - Jérôme Leclercq +// Copyright (C) 2017 Gawaboumga (https://github.com/Gawaboumga) - 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 diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index 843ff6126..9ca7f2ef5 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -64,8 +64,8 @@ namespace Nz Rect& Translate(const Vector2& translation); - T& operator[](unsigned int i); - T operator[](unsigned int i) const; + T& operator[](std::size_t i); + T operator[](std::size_t i) const; Rect operator*(T scalar) const; Rect operator*(const Vector2& vec) const; diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 21d0e7e93..f5d96c249 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) 2017 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 @@ -117,8 +117,8 @@ namespace Nz 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); } /*! @@ -578,23 +578,14 @@ namespace Nz * \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 + * \remark Produce a NazaraError if you try to access to index greater 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) + T& Rect::operator[](std::size_t i) { - #if NAZARA_MATH_SAFE - if (i >= 4) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 4, "Index out of range"); return *(&x+i); } @@ -603,24 +594,15 @@ namespace Nz * \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 + * \remark Access to index greater than 4 is undefined behavior + * \remark Produce a NazaraError if you try to access to index greater 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 + T Rect::operator[](std::size_t i) const { - #if NAZARA_MATH_SAFE - if (i >= 4) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 4, "Index out of range"); return *(&x+i); } diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 8f7ac9e14..cfa693507 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -58,13 +58,10 @@ namespace Nz Sphere& Set(const T sphere[4]); template Sphere& Set(const Sphere& sphere); - T SquaredDistance(T X, T Y, T Z) const; - T SquaredDistance(const Vector3& point) const; - String ToString() const; - T& operator[](unsigned int i); - T operator[](unsigned int i) const; + T& operator[](std::size_t i); + T operator[](std::size_t i) const; Sphere operator*(T scalar) const; Sphere& operator=(const Sphere& other) = default; diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 0a8d1adae..5aede77c2 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -94,7 +94,7 @@ namespace Nz template bool Sphere::Contains(T X, T Y, T Z) const { - return SquaredDistance(X, Y, Z) <= radius * radius; + return Contains(Vector3(X, Y, Z)); } /*! @@ -109,11 +109,8 @@ namespace Nz template bool Sphere::Contains(const Box& box) const { - if (box.GetMinimum().SquaredDistance(GetPosition()) <= radius * radius) - { - if (box.GetMaximum().SquaredDistance(GetPosition()) <= radius * radius) - return true; - } + if (Contains(box.GetMinimum()) && Contains(box.GetMaximum())) + return true; return false; } @@ -128,7 +125,7 @@ namespace Nz template bool Sphere::Contains(const Vector3& point) const { - return Contains(point.x, point.y, point.z); + return GetPosition().SquaredDistance(point) <= radius * radius; } /*! @@ -138,8 +135,6 @@ namespace Nz * \param X X position of the point * \param Y Y position of the point * \param Z Z position of the point - * - * \see SquaredDistance */ template @@ -153,8 +148,6 @@ namespace Nz * \return Distance to the point * * \param point Position of the point - * - * \see SquaredDistance */ template @@ -177,9 +170,7 @@ namespace Nz template Sphere& Sphere::ExtendTo(T X, T Y, T Z) { - T distance = SquaredDistance(X, Y, Z); - if (distance > radius*radius) - radius = std::sqrt(distance); + radius = std::max(radius, radius + Distance(X, Y, Z)); return *this; } @@ -304,7 +295,7 @@ namespace Nz template bool Sphere::Intersect(const Sphere& sphere) const { - return SquaredDistance(sphere.x, sphere.y, sphere.z) <= sphere.radius * sphere.radius; + return GetPosition().SquaredDistance(Vector3(sphere.x, sphere.y, sphere.z)) <= IntegralPow(radius + sphere.radius, 2); } /*! @@ -458,36 +449,6 @@ namespace Nz return *this; } - /*! - * \brief Returns the squared distance from the sphere to the point (can be negative if the point is inside the sphere) - * \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 - { - return SquaredDistance({X, Y, Z}); - } - - /*! - * \brief Returns the squared distance from the sphere to the point (can be negative if the point is inside the sphere) - * \return Squared distance to the point - * - * \param point Position of the point - * - * \see Distance - */ - template - T Sphere::SquaredDistance(const Vector3& point) const - { - return Vector3f::SquaredDistance(point, GetPosition() + (point - GetPosition()).Normalize() * radius); - } - /*! * \brief Gives a string representation * \return A string representation of the object: "Sphere(x, y, z; radius)" @@ -505,24 +466,15 @@ namespace Nz * \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 + * \remark Access to index greater than 4 is undefined behavior + * \remark Produce a NazaraError if you try to access to index greater 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) + T& Sphere::operator[](std::size_t i) { - #if NAZARA_MATH_SAFE - if (i >= 4) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 4, "Index out of range"); return *(&x+i); } @@ -531,24 +483,15 @@ namespace Nz * \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 + * \remark Access to index greater than 4 is undefined behavior + * \remark Produce a NazaraError if you try to access to index greater 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 + T Sphere::operator[](std::size_t i) const { - #if NAZARA_MATH_SAFE - if (i >= 4) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 4, "Index out of range"); return *(&x+i); } diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 49890b06f..ecbd5e4fe 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 8ca023843..1883ecfdc 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 27681683f..8cfe59397 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2017 Rémi Bèges - 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 diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 604cbfb86..37be47fba 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2017 Rémi Bèges - 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 diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index d878c2ea5..c39c0b250 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2017 Rémi Bèges - 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 diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index f3cad0a31..b79e6a644 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2017 Rémi Bèges - 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 diff --git a/include/Nazara/Network.hpp b/include/Nazara/Network.hpp index 41b7fce71..1b2dc72c5 100644 --- a/include/Nazara/Network.hpp +++ b/include/Nazara/Network.hpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index f3789ebf0..0b33c6a8f 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -34,6 +34,11 @@ namespace Nz inline bool IsBlockingEnabled() const; std::size_t QueryAvailableBytes() const; + std::size_t QueryReceiveBufferSize() const; + std::size_t QuerySendBufferSize() const; + + void SetReceiveBufferSize(std::size_t size); + void SetSendBufferSize(std::size_t size); AbstractSocket& operator=(const AbstractSocket&) = delete; AbstractSocket& operator=(AbstractSocket&& abstractSocket); @@ -63,4 +68,4 @@ namespace Nz #include -#endif // NAZARA_ABSTRACTSOCKET_HPP \ No newline at end of file +#endif // NAZARA_ABSTRACTSOCKET_HPP diff --git a/include/Nazara/Network/AbstractSocket.inl b/include/Nazara/Network/AbstractSocket.inl index 5b5174b98..fe8aed5af 100644 --- a/include/Nazara/Network/AbstractSocket.inl +++ b/include/Nazara/Network/AbstractSocket.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/Algorithm.hpp b/include/Nazara/Network/Algorithm.hpp index ec8164ef4..2c0467e64 100644 --- a/include/Nazara/Network/Algorithm.hpp +++ b/include/Nazara/Network/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -9,12 +9,23 @@ #include #include +#include #include #include +#include namespace Nz { + NAZARA_NETWORK_API const char* ErrorToString(Nz::ResolveError resolveError); + NAZARA_NETWORK_API const char* ErrorToString(Nz::SocketError socketError); + NAZARA_NETWORK_API bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port = nullptr, bool* isIPv6 = nullptr, const char** endOfRead = nullptr); + + template + std::enable_if_t::value, T> HostToNet(T value); + + template + std::enable_if_t::value, T> NetToHost(T value); } #include diff --git a/include/Nazara/Network/Algorithm.inl b/include/Nazara/Network/Algorithm.inl index ecf609987..4cba24136 100644 --- a/include/Nazara/Network/Algorithm.inl +++ b/include/Nazara/Network/Algorithm.inl @@ -1,7 +1,32 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 +{ + template + std::enable_if_t::value, T> HostToNet(T value) + { +#ifdef NAZARA_LITTLE_ENDIAN + return SwapBytes(value); +#else + return value; +#endif + } + + template + std::enable_if_t::value, T> NetToHost(T value) + { +#ifdef NAZARA_LITTLE_ENDIAN + return SwapBytes(value); +#else + return value; +#endif + } +} + #include diff --git a/include/Nazara/Network/ConfigCheck.hpp b/include/Nazara/Network/ConfigCheck.hpp index 2f1ba1dc8..c17f870dc 100644 --- a/include/Nazara/Network/ConfigCheck.hpp +++ b/include/Nazara/Network/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/Debug.hpp b/include/Nazara/Network/Debug.hpp index 0826a3ecc..40f5296fa 100644 --- a/include/Nazara/Network/Debug.hpp +++ b/include/Nazara/Network/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/DebugOff.hpp b/include/Nazara/Network/DebugOff.hpp index e9df99f1f..d6bf6d17f 100644 --- a/include/Nazara/Network/DebugOff.hpp +++ b/include/Nazara/Network/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/ENetHost.hpp b/include/Nazara/Network/ENetHost.hpp new file mode 100644 index 000000000..eb5c7d6de --- /dev/null +++ b/include/Nazara/Network/ENetHost.hpp @@ -0,0 +1,166 @@ +/* + Copyright(c) 2002 - 2016 Lee Salzman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Copyright (C) 2017 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_ENETHOST_HPP +#define NAZARA_ENETHOST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API ENetHost + { + friend ENetPeer; + friend class Network; + + public: + inline ENetHost(); + ENetHost(const ENetHost&) = delete; + ENetHost(ENetHost&&) = default; + inline ~ENetHost(); + + void Broadcast(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet); + + bool CheckEvents(ENetEvent* event); + + ENetPeer* Connect(const IpAddress& remoteAddress, std::size_t channelCount = 0, UInt32 data = 0); + ENetPeer* Connect(const String& hostName, NetProtocol protocol = NetProtocol_Any, const String& service = "http", ResolveError* error = nullptr, std::size_t channelCount = 0, UInt32 data = 0); + + inline bool Create(NetProtocol protocol, UInt16 port, std::size_t peerCount, std::size_t channelCount = 0); + bool Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount = 0); + bool Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth); + void Destroy(); + + void Flush(); + + inline Nz::IpAddress GetBoundAddress() const; + inline UInt32 GetServiceTime() const; + + int Service(ENetEvent* event, UInt32 timeout); + + void SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay); + + ENetHost& operator=(const ENetHost&) = delete; + ENetHost& operator=(ENetHost&&) = default; + + private: + ENetPacketRef AllocatePacket(ENetPacketFlags flags); + inline ENetPacketRef AllocatePacket(ENetPacketFlags flags, NetPacket&& data); + + bool InitSocket(const IpAddress& address); + + void AddToDispatchQueue(ENetPeer* peer); + void RemoveFromDispatchQueue(ENetPeer* peer); + + bool DispatchIncomingCommands(ENetEvent* event); + + ENetPeer* HandleConnect(ENetProtocolHeader* header, ENetProtocol* command); + bool HandleIncomingCommands(ENetEvent* event); + + int ReceiveIncomingCommands(ENetEvent* event); + + void NotifyConnect(ENetPeer* peer, ENetEvent* event, bool incoming); + void NotifyDisconnect(ENetPeer*, ENetEvent* event); + + void SendAcknowledgements(ENetPeer* peer); + bool SendReliableOutgoingCommands(ENetPeer* peer); + int SendOutgoingCommands(ENetEvent* event, bool checkForTimeouts); + void SendUnreliableOutgoingCommands(ENetPeer* peer); + + void ThrottleBandwidth(); + + static std::size_t GetCommandSize(UInt8 commandNumber); + static bool Initialize(); + static void Uninitialize(); + + struct PendingIncomingPacket + { + IpAddress from; + NetPacket data; + UInt32 deliveryTime; + }; + + struct PendingOutgoingPacket + { + IpAddress to; + NetPacket data; + UInt32 deliveryTime; + }; + + std::array m_commands; + std::array m_buffers; + std::array m_packetData[2]; + std::bernoulli_distribution m_packetLossProbability; + std::size_t m_bandwidthLimitedPeers; + std::size_t m_bufferCount; + std::size_t m_channelLimit; + std::size_t m_commandCount; + std::size_t m_duplicatePeers; + std::size_t m_maximumPacketSize; + std::size_t m_maximumWaitingData; + std::size_t m_packetSize; + std::size_t m_peerCount; + std::size_t m_receivedDataLength; + std::uniform_int_distribution m_packetDelayDistribution; + std::vector m_peers; + std::vector m_pendingIncomingPackets; + std::vector m_pendingOutgoingPackets; + UInt8* m_receivedData; + Bitset m_dispatchQueue; + MemoryPool m_packetPool; + IpAddress m_address; + IpAddress m_receivedAddress; + SocketPoller m_poller; + UdpSocket m_socket; + UInt16 m_headerFlags; + UInt32 m_bandwidthThrottleEpoch; + UInt32 m_connectedPeers; + UInt32 m_mtu; + UInt32 m_randomSeed; + UInt32 m_incomingBandwidth; + UInt32 m_outgoingBandwidth; + UInt32 m_serviceTime; + UInt32 m_totalSentPackets; + UInt32 m_totalReceivedPackets; + UInt64 m_totalSentData; + UInt64 m_totalReceivedData; + bool m_continueSending; + bool m_isSimulationEnabled; + bool m_recalculateBandwidthLimits; + + static std::mt19937 s_randomGenerator; + static std::mt19937_64 s_randomGenerator64; + }; +} + +#include + +#endif // NAZARA_ENETHOST_HPP diff --git a/include/Nazara/Network/ENetHost.inl b/include/Nazara/Network/ENetHost.inl new file mode 100644 index 000000000..3f35a8f39 --- /dev/null +++ b/include/Nazara/Network/ENetHost.inl @@ -0,0 +1,74 @@ +// Copyright (C) 2017 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 ENetHost::ENetHost() : + m_packetPool(sizeof(ENetPacket)), + m_isSimulationEnabled(false) + { + } + + inline ENetHost::~ENetHost() + { + Destroy(); + } + + inline bool ENetHost::Create(NetProtocol protocol, UInt16 port, std::size_t peerCount, std::size_t channelCount) + { + 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 Create(any, peerCount, channelCount); + } + + inline void ENetHost::Destroy() + { + m_poller.Clear(); + m_peers.clear(); + m_socket.Close(); + } + + inline Nz::IpAddress ENetHost::GetBoundAddress() const + { + return m_address; + } + + inline UInt32 Nz::ENetHost::GetServiceTime() const + { + return m_serviceTime; + } + + inline ENetPacketRef ENetHost::AllocatePacket(ENetPacketFlags flags, NetPacket&& data) + { + ENetPacketRef ref = AllocatePacket(flags); + ref->data = std::move(data); + + return ref; + } +} + +#include diff --git a/include/Nazara/Network/ENetPacket.hpp b/include/Nazara/Network/ENetPacket.hpp new file mode 100644 index 000000000..54b0c42c6 --- /dev/null +++ b/include/Nazara/Network/ENetPacket.hpp @@ -0,0 +1,107 @@ +// Copyright (C) 2017 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_ENETPACKET_HPP +#define NAZARA_ENETPACKET_HPP + +#include +#include + +namespace Nz +{ + enum ENetPacketFlag + { + ENetPacketFlag_Reliable, + ENetPacketFlag_Unsequenced, + ENetPacketFlag_UnreliableFragment + }; + + template<> + struct EnumAsFlags + { + static constexpr bool value = true; + static constexpr int max = ENetPacketFlag_UnreliableFragment; + }; + + using ENetPacketFlags = Flags; + + constexpr ENetPacketFlags ENetPacketFlag_Unreliable = 0; + + class MemoryPool; + + struct ENetPacket + { + MemoryPool* owner; + ENetPacketFlags flags; + NetPacket data; + std::size_t referenceCount = 0; + }; + + struct NAZARA_NETWORK_API ENetPacketRef + { + ENetPacketRef() = default; + + ENetPacketRef(ENetPacket* packet) + { + Reset(packet); + } + + ENetPacketRef(const ENetPacketRef& packet) : + ENetPacketRef() + { + Reset(packet); + } + + ENetPacketRef(ENetPacketRef&& packet) : + m_packet(packet.m_packet) + { + packet.m_packet = nullptr; + } + + ~ENetPacketRef() + { + Reset(); + } + + void Reset(ENetPacket* packet = nullptr); + + operator ENetPacket*() const + { + return m_packet; + } + + ENetPacket* operator->() const + { + return m_packet; + } + + ENetPacketRef& operator=(ENetPacket* packet) + { + Reset(packet); + + return *this; + } + + ENetPacketRef& operator=(const ENetPacketRef& packet) + { + Reset(packet); + + return *this; + } + + ENetPacketRef& operator=(ENetPacketRef&& packet) + { + m_packet = packet.m_packet; + packet.m_packet = nullptr; + + return *this; + } + + ENetPacket* m_packet = nullptr; + }; +} + +#endif // NAZARA_ENETPACKET_HPP diff --git a/include/Nazara/Network/ENetPeer.hpp b/include/Nazara/Network/ENetPeer.hpp new file mode 100644 index 000000000..4e36378a5 --- /dev/null +++ b/include/Nazara/Network/ENetPeer.hpp @@ -0,0 +1,248 @@ +/* + Copyright(c) 2002 - 2016 Lee Salzman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Copyright (C) 2017 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_ENETPEER_HPP +#define NAZARA_ENETPEER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class ENetHost; + + class NAZARA_NETWORK_API ENetPeer + { + friend ENetHost; + friend struct PacketRef; + + public: + inline ENetPeer(ENetHost* host, UInt16 peerId); + ENetPeer(const ENetPeer&) = delete; + ENetPeer(ENetPeer&&) = default; + ~ENetPeer() = default; + + void Disconnect(UInt32 data); + void DisconnectLater(UInt32 data); + void DisconnectNow(UInt32 data); + + inline const IpAddress& GetAddress() const; + inline UInt32 GetMtu() const; + inline UInt32 GetPacketThrottleAcceleration() const; + inline UInt32 GetPacketThrottleDeceleration() const; + inline UInt32 GetPacketThrottleInterval() const; + inline UInt16 GetPeerId() const; + inline UInt32 GetRoundTripTime() const; + inline ENetPeerState GetState() const; + + inline bool HasPendingCommands(); + + inline bool IsConnected() const; + inline bool IsSimulationEnabled() const; + + void Ping(); + + bool Receive(ENetPacketRef* packet, UInt8* channelId); + void Reset(); + + bool Send(UInt8 channelId, ENetPacketRef packetRef); + bool Send(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet); + + void SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay); + + void ThrottleConfigure(UInt32 interval, UInt32 acceleration, UInt32 deceleration); + + ENetPeer& operator=(const ENetPeer&) = delete; + ENetPeer& operator=(ENetPeer&&) = default; + + private: + void InitIncoming(std::size_t channelCount, const IpAddress& address, ENetProtocolConnect& incomingCommand); + void InitOutgoing(std::size_t channelCount, const IpAddress& address, UInt32 connectId, UInt32 windowSize); + + struct Acknowledgement; + struct Channel; + struct IncomingCommmand; + struct OutgoingCommand; + + inline void ChangeState(ENetPeerState state); + + bool CheckTimeouts(ENetEvent* event); + + void DispatchState(ENetPeerState state); + + void DispatchIncomingReliableCommands(Channel& channel); + void DispatchIncomingUnreliableCommands(Channel& channel); + + bool HandleAcknowledge(const ENetProtocol* command, ENetEvent* event); + bool HandleBandwidthLimit(const ENetProtocol* command); + bool HandleDisconnect(const ENetProtocol* command); + bool HandlePing(const ENetProtocol* command); + bool HandleSendFragment(const ENetProtocol* command, UInt8** data); + bool HandleSendReliable(const ENetProtocol* command, UInt8** data); + bool HandleSendUnreliable(const ENetProtocol* command, UInt8** data); + bool HandleSendUnreliableFragment(const ENetProtocol* command, UInt8** data); + bool HandleSendUnsequenced(const ENetProtocol* command, UInt8** data); + bool HandleThrottleConfigure(const ENetProtocol* command); + bool HandleVerifyConnect(const ENetProtocol* command, ENetEvent* event); + + void OnConnect(); + void OnDisconnect(); + + ENetProtocolCommand RemoveSentReliableCommand(UInt16 reliableSequenceNumber, UInt8 channelId); + void RemoveSentUnreliableCommands(); + + void ResetQueues(); + + bool QueueAcknowledgement(ENetProtocol* command, UInt16 sentTime); + IncomingCommmand* QueueIncomingCommand(const ENetProtocol& command, const void* data, std::size_t dataLength, UInt32 flags, UInt32 fragmentCount); + inline void QueueOutgoingCommand(ENetProtocol& command); + void QueueOutgoingCommand(ENetProtocol& command, ENetPacketRef packet, UInt32 offset, UInt16 length); + + void SetupOutgoingCommand(OutgoingCommand& outgoingCommand); + + int Throttle(UInt32 rtt); + + struct Acknowledgement + { + ENetProtocol command; + UInt32 sentTime; + }; + + struct Channel + { + Channel() + { + incomingReliableSequenceNumber = 0; + incomingUnreliableSequenceNumber = 0; + outgoingReliableSequenceNumber = 0; + outgoingUnreliableSequenceNumber = 0; + usedReliableWindows = 0; + reliableWindows.fill(0); + } + + std::array reliableWindows; + std::list incomingReliableCommands; + std::list incomingUnreliableCommands; + UInt16 incomingReliableSequenceNumber; + UInt16 incomingUnreliableSequenceNumber; + UInt16 outgoingReliableSequenceNumber; + UInt16 outgoingUnreliableSequenceNumber; + UInt16 usedReliableWindows; + }; + + struct IncomingCommmand + { + ENetProtocol command; + Bitset<> fragments; + ENetPacketRef packet; + UInt16 reliableSequenceNumber; + UInt16 unreliableSequenceNumber; + UInt32 fragmentsRemaining; + }; + + struct OutgoingCommand + { + ENetProtocol command; + ENetPacketRef packet; + UInt16 fragmentLength; + UInt16 reliableSequenceNumber; + UInt16 sendAttempts; + UInt16 unreliableSequenceNumber; + UInt32 fragmentOffset; + UInt32 roundTripTimeout; + UInt32 roundTripTimeoutLimit; + UInt32 sentTime; + }; + + static constexpr std::size_t unsequencedWindow = ENetPeer_ReliableWindowSize / 32; + + ENetHost* m_host; + IpAddress m_address; /**< Internet address of the peer */ + std::array m_unsequencedWindow; + std::bernoulli_distribution m_packetLossProbability; + std::list m_dispatchedCommands; + std::list m_outgoingReliableCommands; + std::list m_outgoingUnreliableCommands; + std::list m_sentReliableCommands; + std::list m_sentUnreliableCommands; + std::size_t m_totalWaitingData; + std::uniform_int_distribution m_packetDelayDistribution; + std::vector m_acknowledgements; + std::vector m_channels; + ENetPeerState m_state; + UInt8 m_incomingSessionID; + UInt8 m_outgoingSessionID; + UInt16 m_incomingPeerID; + UInt16 m_incomingUnsequencedGroup; + UInt16 m_outgoingPeerID; + UInt16 m_outgoingReliableSequenceNumber; + UInt16 m_outgoingUnsequencedGroup; + UInt32 m_connectID; + UInt32 m_earliestTimeout; + UInt32 m_eventData; + UInt32 m_highestRoundTripTimeVariance; + UInt32 m_incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ + UInt32 m_incomingBandwidthThrottleEpoch; + UInt32 m_incomingDataTotal; + UInt32 m_lastReceiveTime; + UInt32 m_lastRoundTripTime; + UInt32 m_lastRoundTripTimeVariance; + UInt32 m_lastSendTime; + UInt32 m_lowestRoundTripTime; + UInt32 m_mtu; + UInt32 m_nextTimeout; + UInt32 m_outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ + UInt32 m_outgoingBandwidthThrottleEpoch; + UInt32 m_outgoingDataTotal; + UInt32 m_packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ + UInt32 m_packetLossEpoch; + UInt32 m_packetLossVariance; + UInt32 m_packetThrottle; + UInt32 m_packetThrottleAcceleration; + UInt32 m_packetThrottleCounter; + UInt32 m_packetThrottleDeceleration; + UInt32 m_packetThrottleEpoch; + UInt32 m_packetThrottleInterval; + UInt32 m_packetThrottleLimit; + UInt32 m_packetsLost; + UInt32 m_packetsSent; + UInt32 m_pingInterval; + UInt32 m_reliableDataInTransit; + UInt32 m_roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgment */ + UInt32 m_roundTripTimeVariance; + UInt32 m_timeoutLimit; + UInt32 m_timeoutMaximum; + UInt32 m_timeoutMinimum; + UInt32 m_windowSize; + UInt64 m_totalPacketLost; + UInt64 m_totalPacketSent; + bool m_isSimulationEnabled; + }; +} + +#include + +#endif // NAZARA_ENETPEER_HPP diff --git a/include/Nazara/Network/ENetPeer.inl b/include/Nazara/Network/ENetPeer.inl new file mode 100644 index 000000000..d831b4d0d --- /dev/null +++ b/include/Nazara/Network/ENetPeer.inl @@ -0,0 +1,92 @@ +// Copyright (C) 2017 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 ENetPeer::ENetPeer(ENetHost* host, UInt16 peerId) : + m_host(host), + m_incomingSessionID(0xFF), + m_outgoingSessionID(0xFF), + m_incomingPeerID(peerId), + m_isSimulationEnabled(false) + { + Reset(); + } + + inline const IpAddress& ENetPeer::GetAddress() const + { + return m_address; + } + + inline UInt32 ENetPeer::GetMtu() const + { + return m_mtu; + } + + inline UInt32 ENetPeer::GetPacketThrottleAcceleration() const + { + return m_packetThrottleAcceleration; + } + + inline UInt32 ENetPeer::GetPacketThrottleDeceleration() const + { + return m_packetThrottleDeceleration; + } + + inline UInt32 ENetPeer::GetPacketThrottleInterval() const + { + return m_packetThrottleInterval; + } + + inline UInt16 ENetPeer::GetPeerId() const + { + return m_incomingPeerID; + } + + inline UInt32 ENetPeer::GetRoundTripTime() const + { + return m_roundTripTime; + } + + inline ENetPeerState ENetPeer::GetState() const + { + return m_state; + } + + inline bool ENetPeer::HasPendingCommands() + { + return m_outgoingReliableCommands.empty() && m_outgoingUnreliableCommands.empty() && m_sentReliableCommands.empty(); + } + + inline bool ENetPeer::IsConnected() const + { + return m_state == ENetPeerState::Connected || m_state == ENetPeerState::DisconnectLater; + } + + inline bool ENetPeer::IsSimulationEnabled() const + { + return m_isSimulationEnabled; + } + + inline void ENetPeer::ChangeState(ENetPeerState state) + { + if (state == ENetPeerState::Connected || state == ENetPeerState::DisconnectLater) + OnConnect(); + else + OnDisconnect(); + + m_state = state; + } + + inline void ENetPeer::QueueOutgoingCommand(ENetProtocol& command) + { + QueueOutgoingCommand(command, ENetPacketRef(), 0, 0); + } +} + +#include diff --git a/include/Nazara/Network/ENetProtocol.hpp b/include/Nazara/Network/ENetProtocol.hpp new file mode 100644 index 000000000..dab014aa2 --- /dev/null +++ b/include/Nazara/Network/ENetProtocol.hpp @@ -0,0 +1,311 @@ +// Copyright (C) 2017 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_ENETPROTOCOL_HPP +#define NAZARA_ENETPROTOCOL_HPP + +#include +#include +#include + +namespace Nz +{ + constexpr UInt32 ENetTimeOverflow = 24 * 60 * 60 * 1000; + + inline UInt32 ENetTimeDifference(UInt32 a, UInt32 b); + inline bool ENetTimeLess(UInt32 a, UInt32 b); + inline bool ENetTimeLessEqual(UInt32 a, UInt32 b); + inline bool ENetTimeGreater(UInt32 a, UInt32 b); + inline bool ENetTimeGreaterEqual(UInt32 a, UInt32 b); + + class ENetPeer; + + // Constants for the ENet implementation and protocol + enum ENetConstants + { + ENetHost_BandwidthThrottleInterval = 1000, + ENetHost_DefaultMaximumPacketSize = 32 * 1024 * 1024, + ENetHost_DefaultMaximumWaitingData = 32 * 1024 * 1024, + ENetHost_DefaultMTU = 1400, + ENetHost_ReceiveBufferSize = 256 * 1024, + ENetHost_SendBufferSize = 256 * 1024, + + ENetPeer_DefaultPacketThrottle = 32, + ENetPeer_DefaultRoundTripTime = 500, + ENetPeer_FreeReliableWindows = 8, + ENetPeer_FreeUnsequencedWindows = 32, + ENetPeer_PacketLossInterval = 10000, + ENetPeer_PacketLossScale = (1 << 16), + ENetPeer_PacketThrottleAcceleration = 2, + ENetPeer_PacketThrottleCounter = 7, + ENetPeer_PacketThrottleDeceleration = 2, + ENetPeer_PacketThrottleInterval = 5000, + ENetPeer_PacketThrottleScale = 32, + ENetPeer_PingInterval = 500, + ENetPeer_ReliableWindows = 16, + ENetPeer_ReliableWindowSize = 0x1000, + ENetPeer_TimeoutLimit = 32, + ENetPeer_TimeoutMaximum = 30000, + ENetPeer_TimeoutMinimum = 5000, + ENetPeer_UnsequencedWindows = 64, + ENetPeer_UnsequencedWindowSize = 1024, + ENetPeer_WindowSizeScale = 64 * 1024, + + ENetProtocol_MaximumChannelCount = 255, + ENetProtocol_MaximumFragmentCount = 1024 * 1024, + ENetProtocol_MaximumMTU = 4096, + ENetProtocol_MaximumPacketCommands = 32, + ENetProtocol_MaximumPeerId = 0xFFF, + ENetProtocol_MaximumWindowSize = 65536, + ENetProtocol_MinimumChannelCount = 1, + ENetProtocol_MinimumMTU = 576, + ENetProtocol_MinimumWindowSize = 4096 + }; + + enum class ENetPeerState + { + AcknowledgingConnect = 2, + AcknowledgingDisconnect = 8, + Connecting = 1, + ConnectionPending = 3, + ConnectionSucceeded = 4, + Connected = 5, + Disconnected = 0, + Disconnecting = 7, + DisconnectLater = 6, + Zombie = 9 + }; + + enum ENetProtocolCommand + { + // Keeping the values is important for compatibility with the native ENet protocol + ENetProtocolCommand_Acknowledge = 1, + ENetProtocolCommand_BandwidthLimit = 10, + ENetProtocolCommand_Connect = 2, + ENetProtocolCommand_Disconnect = 4, + ENetProtocolCommand_None = 0, + ENetProtocolCommand_Ping = 5, + ENetProtocolCommand_SendFragment = 8, + ENetProtocolCommand_SendReliable = 6, + ENetProtocolCommand_SendUnreliable = 7, + ENetProtocolCommand_SendUnreliableFragment = 12, + ENetProtocolCommand_SendUnsequenced = 9, + ENetProtocolCommand_ThrottleConfigure = 11, + ENetProtocolCommand_VerifyConnect = 3, + ENetProtocolCommand_Count = 13, + + ENetProtocolCommand_Mask = 0x0F + }; + + enum ENetProtocolFlag + { + ENetProtocolFlag_Acknowledge = (1 << 7), + ENetProtocolFlag_Unsequenced = (1 << 6), + + ENetProtocolHeaderFlag_Compressed = (1 << 14), + ENetProtocolHeaderFlag_SentTime = (1 << 15), + ENetProtocolHeaderFlag_Mask = ENetProtocolHeaderFlag_Compressed | ENetProtocolHeaderFlag_SentTime, + + ENetProtocolHeaderSessionMask = (3 << 12), + ENetProtocolHeaderSessionShift = 12 + }; + + enum class ENetEventType + { + /** no event occurred within the specified time limit */ + None, + + /** a peer has disconnected. This event is generated on a successful + * completion of a disconnect initiated by enet_peer_disconnect, if + * a peer has timed out, or if a connection request initialized by + * enet_host_connect has timed out. The peer field contains the peer + * which disconnected. The data field contains user supplied data + * describing the disconnection, or 0, if none is available. + */ + Disconnect, + + /** a connection request initiated by enet_host_connect from this host has completed. + * The peer field contains the peer which successfully connected. + */ + OutgoingConnect, + + /** a connection request initiated by enet_host_connect from another host has completed. + * The peer field contains the peer which successfully connected. + */ + IncomingConnect, + + /** a packet has been received from a peer. The peer field specifies the + * peer which sent the packet. The channelID field specifies the channel + * number upon which the packet was received. The packet field contains + * the packet that was received; + */ + Receive + }; + + struct ENetEvent + { + ENetEventType type; + ENetPeer* peer; + UInt8 channelId; + UInt32 data; + ENetPacketRef packet; + }; + + + #ifdef _MSC_VER + #pragma pack(push, 1) + #define NAZARA_PACKED + #elif defined(__GNUC__) || defined(__clang__) + #define NAZARA_PACKED __attribute__ ((packed)) + #else + #define NAZARA_PACKED + #endif + + + struct NAZARA_PACKED ENetProtocolHeader + { + UInt16 peerID; + UInt16 sentTime; + }; + + struct NAZARA_PACKED ENetProtocolCommandHeader + { + UInt8 command; + UInt8 channelID; + UInt16 reliableSequenceNumber; + }; + + struct NAZARA_PACKED ENetProtocolAcknowledge + { + ENetProtocolCommandHeader header; + UInt16 receivedReliableSequenceNumber; + UInt16 receivedSentTime; + }; + + struct NAZARA_PACKED ENetProtocolConnect + { + ENetProtocolCommandHeader header; + UInt16 outgoingPeerID; + UInt8 incomingSessionID; + UInt8 outgoingSessionID; + UInt32 mtu; + UInt32 windowSize; + UInt32 channelCount; + UInt32 incomingBandwidth; + UInt32 outgoingBandwidth; + UInt32 packetThrottleInterval; + UInt32 packetThrottleAcceleration; + UInt32 packetThrottleDeceleration; + UInt32 connectID; + UInt32 data; + }; + + struct NAZARA_PACKED ENetProtocolBandwidthLimit + { + ENetProtocolCommandHeader header; + UInt32 incomingBandwidth; + UInt32 outgoingBandwidth; + }; + + struct NAZARA_PACKED ENetProtocolDisconnect + { + ENetProtocolCommandHeader header; + UInt32 data; + }; + + struct NAZARA_PACKED ENetProtocolPing + { + ENetProtocolCommandHeader header; + }; + + struct NAZARA_PACKED ENetProtocolSendFragment + { + ENetProtocolCommandHeader header; + UInt16 startSequenceNumber; + UInt16 dataLength; + UInt32 fragmentCount; + UInt32 fragmentNumber; + UInt32 totalLength; + UInt32 fragmentOffset; + }; + + struct NAZARA_PACKED ENetProtocolSendReliable + { + ENetProtocolCommandHeader header; + UInt16 dataLength; + }; + + struct NAZARA_PACKED ENetProtocolSendUnreliable + { + ENetProtocolCommandHeader header; + UInt16 unreliableSequenceNumber; + UInt16 dataLength; + }; + + struct NAZARA_PACKED ENetProtocolSendUnsequenced + { + ENetProtocolCommandHeader header; + UInt16 unsequencedGroup; + UInt16 dataLength; + }; + + struct NAZARA_PACKED ENetProtocolThrottleConfigure + { + ENetProtocolCommandHeader header; + UInt32 packetThrottleInterval; + UInt32 packetThrottleAcceleration; + UInt32 packetThrottleDeceleration; + }; + + struct NAZARA_PACKED ENetProtocolVerifyConnect + { + ENetProtocolCommandHeader header; + UInt16 outgoingPeerID; + UInt8 incomingSessionID; + UInt8 outgoingSessionID; + UInt32 mtu; + UInt32 windowSize; + UInt32 channelCount; + UInt32 incomingBandwidth; + UInt32 outgoingBandwidth; + UInt32 packetThrottleInterval; + UInt32 packetThrottleAcceleration; + UInt32 packetThrottleDeceleration; + UInt32 connectID; + }; + + union NAZARA_PACKED ENetProtocol + { + ENetProtocol() = default; + + ENetProtocol(UInt8 command, UInt8 channel) + { + header.command = command; + header.channelID = channel; + } + + ENetProtocolCommandHeader header; + ENetProtocolAcknowledge acknowledge; + ENetProtocolBandwidthLimit bandwidthLimit; + ENetProtocolConnect connect; + ENetProtocolDisconnect disconnect; + ENetProtocolPing ping; + ENetProtocolSendReliable sendReliable; + ENetProtocolSendUnreliable sendUnreliable; + ENetProtocolSendUnsequenced sendUnsequenced; + ENetProtocolSendFragment sendFragment; + ENetProtocolThrottleConfigure throttleConfigure; + ENetProtocolVerifyConnect verifyConnect; + }; + + #ifdef _MSC_VER + #pragma pack(pop) + #endif +} + +#include + +#endif // NAZARA_ENETPROTOCOL_HPP diff --git a/include/Nazara/Network/ENetProtocol.inl b/include/Nazara/Network/ENetProtocol.inl new file mode 100644 index 000000000..b854f26c8 --- /dev/null +++ b/include/Nazara/Network/ENetProtocol.inl @@ -0,0 +1,34 @@ +// Copyright (C) 2017 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 + +namespace Nz +{ + UInt32 ENetTimeDifference(UInt32 a, UInt32 b) + { + return (ENetTimeLess(a, b)) ? b - a : a - b; + } + + bool ENetTimeLess(UInt32 a, UInt32 b) + { + return (a - b >= ENetTimeOverflow); + } + + bool ENetTimeLessEqual(UInt32 a, UInt32 b) + { + return !ENetTimeGreater(a, b); + } + + bool ENetTimeGreater(UInt32 a, UInt32 b) + { + return ENetTimeLess(b, a); + } + + bool ENetTimeGreaterEqual(UInt32 a, UInt32 b) + { + return !ENetTimeLess(a, b); + } +} diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 32d9484ae..39bce0dd0 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -7,6 +7,8 @@ #ifndef NAZARA_ENUMS_NETWORK_HPP #define NAZARA_ENUMS_NETWORK_HPP +#include + namespace Nz { enum NetCode : UInt16 @@ -89,6 +91,23 @@ namespace Nz SocketError_Max = SocketError_UnreachableHost }; + enum SocketPollEvent + { + SocketPollEvent_Read, //< One or more sockets is ready for a read operation + SocketPollEvent_Write, //< One or more sockets is ready for a write operation + + SocketPollEvent_Max = SocketPollEvent_Write + }; + + template<> + struct EnumAsFlags + { + static constexpr bool value = true; + static constexpr int max = SocketPollEvent_Max; + }; + + using SocketPollEventFlags = Flags; + enum SocketState { SocketState_Bound, //< The socket is currently bound diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index 32def1031..f5e1ca9d8 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -50,7 +50,7 @@ namespace Nz String ToString() const; inline UInt32 ToUInt32() const; - inline operator bool() const; + inline explicit operator bool() const; IpAddress& operator=(const IpAddress&) = default; IpAddress& operator=(IpAddress&&) = default; diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index ed06b1af7..7e59099d2 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/NetBuffer.hpp b/include/Nazara/Network/NetBuffer.hpp new file mode 100644 index 000000000..0c05c53b2 --- /dev/null +++ b/include/Nazara/Network/NetBuffer.hpp @@ -0,0 +1,21 @@ +// Copyright (C) 2017 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_NETBUFFER_HPP +#define NAZARA_NETBUFFER_HPP + +#include + +namespace Nz +{ + struct NetBuffer + { + void* data; + std::size_t dataLength; + }; +} + +#endif // NAZARA_NETBUFFER_HPP diff --git a/include/Nazara/Network/NetPacket.hpp b/include/Nazara/Network/NetPacket.hpp index 7eef2979a..9d5bb99a4 100644 --- a/include/Nazara/Network/NetPacket.hpp +++ b/include/Nazara/Network/NetPacket.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index e9765c9dc..eb68d1e53 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -155,7 +155,9 @@ namespace Nz { InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly); m_buffer->Resize(HeaderSize + size); - std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size); + + if (ptr) + std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size); m_netCode = netCode; } diff --git a/include/Nazara/Network/Network.hpp b/include/Nazara/Network/Network.hpp index 16cf940d2..ca6ca9ee6 100644 --- a/include/Nazara/Network/Network.hpp +++ b/include/Nazara/Network/Network.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/RUdpConnection.hpp b/include/Nazara/Network/RUdpConnection.hpp index 6166d787a..3cdb6c3be 100644 --- a/include/Nazara/Network/RUdpConnection.hpp +++ b/include/Nazara/Network/RUdpConnection.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index 2960cbced..eaf4a0e7a 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/RUdpMessage.hpp b/include/Nazara/Network/RUdpMessage.hpp index 5d4fdb4a5..d0c10197c 100644 --- a/include/Nazara/Network/RUdpMessage.hpp +++ b/include/Nazara/Network/RUdpMessage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/SocketHandle.hpp b/include/Nazara/Network/SocketHandle.hpp index 2a09b80c3..be87e1da7 100644 --- a/include/Nazara/Network/SocketHandle.hpp +++ b/include/Nazara/Network/SocketHandle.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/SocketPoller.hpp b/include/Nazara/Network/SocketPoller.hpp index 0684ef41f..c801ca5e2 100644 --- a/include/Nazara/Network/SocketPoller.hpp +++ b/include/Nazara/Network/SocketPoller.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -24,10 +24,11 @@ namespace Nz void Clear(); - bool IsReady(const AbstractSocket& socket) const; + bool IsReadyToRead(const AbstractSocket& socket) const; + bool IsReadyToWrite(const AbstractSocket& socket) const; bool IsRegistered(const AbstractSocket& socket) const; - bool RegisterSocket(AbstractSocket& socket); + bool RegisterSocket(AbstractSocket& socket, SocketPollEventFlags eventFlags); void UnregisterSocket(AbstractSocket& socket); bool Wait(UInt64 msTimeout); @@ -41,4 +42,4 @@ namespace Nz #include -#endif // NAZARA_SOCKETPOLLER_HPP \ No newline at end of file +#endif // NAZARA_SOCKETPOLLER_HPP diff --git a/include/Nazara/Network/SocketPoller.inl b/include/Nazara/Network/SocketPoller.inl index c3e415508..66331b9cb 100644 --- a/include/Nazara/Network/SocketPoller.inl +++ b/include/Nazara/Network/SocketPoller.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index 0fcedcf39..a3b229bda 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -13,6 +13,7 @@ #include #include #include +#include namespace Nz { @@ -49,6 +50,7 @@ namespace Nz bool ReceivePacket(NetPacket* packet); bool Send(const void* buffer, std::size_t size, std::size_t* sent); + bool SendMultiple(const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent); bool SendPacket(const NetPacket& packet); bool SetCursorPos(UInt64 offset) override; diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index 23f5412da..0ab267436 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/TcpServer.hpp b/include/Nazara/Network/TcpServer.hpp index da1b48e73..9eab2f0a3 100644 --- a/include/Nazara/Network/TcpServer.hpp +++ b/include/Nazara/Network/TcpServer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl index 1fcb4eb32..c3aedbd0e 100644 --- a/include/Nazara/Network/TcpServer.inl +++ b/include/Nazara/Network/TcpServer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index 2aac124af..0086249e9 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -10,6 +10,7 @@ #include #include #include +#include namespace Nz { @@ -29,10 +30,9 @@ namespace Nz inline bool Create(NetProtocol protocol); void EnableBroadcasting(bool broadcasting); - + inline IpAddress GetBoundAddress() const; inline UInt16 GetBoundPort() const; - inline SocketState GetState() const; inline bool IsBroadcastingEnabled() const; @@ -42,6 +42,7 @@ namespace Nz bool ReceivePacket(NetPacket* packet, IpAddress* from); bool Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent); + bool SendMultiple(const IpAddress& to, const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent); bool SendPacket(const IpAddress& to, const NetPacket& packet); private: @@ -55,4 +56,4 @@ namespace Nz #include -#endif // NAZARA_UDPSOCKET_HPP \ No newline at end of file +#endif // NAZARA_UDPSOCKET_HPP diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index 4096d8c04..2925c1935 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -103,16 +103,6 @@ namespace Nz return m_boundAddress.GetPort(); } - /*! - * \brief Gets the state of the socket - * \return State of the socket - */ - - inline SocketState UdpSocket::GetState() const - { - return m_state; - } - /*! * \brief Checks whether the broadcasting is enabled * \return true If it is the case diff --git a/include/Nazara/Noise/ConfigCheck.hpp b/include/Nazara/Noise/ConfigCheck.hpp index 9c6df7851..93a90e13f 100644 --- a/include/Nazara/Noise/ConfigCheck.hpp +++ b/include/Nazara/Noise/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Debug.hpp b/include/Nazara/Noise/Debug.hpp index 4696c79b9..4068c5a95 100644 --- a/include/Nazara/Noise/Debug.hpp +++ b/include/Nazara/Noise/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/DebugOff.hpp b/include/Nazara/Noise/DebugOff.hpp index 4b368b6ea..a0ca07927 100644 --- a/include/Nazara/Noise/DebugOff.hpp +++ b/include/Nazara/Noise/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Enums.hpp b/include/Nazara/Noise/Enums.hpp index 7962d8415..fdc2b7ec3 100644 --- a/include/Nazara/Noise/Enums.hpp +++ b/include/Nazara/Noise/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/FBM.hpp b/include/Nazara/Noise/FBM.hpp index 584fb3a10..41cbc5758 100644 --- a/include/Nazara/Noise/FBM.hpp +++ b/include/Nazara/Noise/FBM.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/HybridMultiFractal.hpp b/include/Nazara/Noise/HybridMultiFractal.hpp index cbb80ef65..78d94f4de 100644 --- a/include/Nazara/Noise/HybridMultiFractal.hpp +++ b/include/Nazara/Noise/HybridMultiFractal.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/MixerBase.hpp b/include/Nazara/Noise/MixerBase.hpp index 8b7a99d56..954932114 100644 --- a/include/Nazara/Noise/MixerBase.hpp +++ b/include/Nazara/Noise/MixerBase.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -15,7 +15,7 @@ namespace Nz { public: MixerBase(); - ~MixerBase() = default; + virtual ~MixerBase() = default; virtual float Get(float x, float y, float scale) const = 0; virtual float Get(float x, float y, float z, float scale) const = 0; diff --git a/include/Nazara/Noise/Noise.hpp b/include/Nazara/Noise/Noise.hpp index c1ec5b1da..8138ee41b 100644 --- a/include/Nazara/Noise/Noise.hpp +++ b/include/Nazara/Noise/Noise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index f7f9eba09..dc57a6e40 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -19,7 +19,7 @@ namespace Nz { public: NoiseBase(unsigned int seed = 0); - ~NoiseBase() = default; + virtual ~NoiseBase() = default; virtual float Get(float x, float y, float scale) const = 0; virtual float Get(float x, float y, float z, float scale) const = 0; @@ -40,7 +40,7 @@ namespace Nz static std::array s_gradients4; private: - std::default_random_engine m_randomEngine; + std::mt19937 m_randomEngine; }; } diff --git a/include/Nazara/Noise/NoiseTools.hpp b/include/Nazara/Noise/NoiseTools.hpp index 6238caec3..b3fd1bada 100644 --- a/include/Nazara/Noise/NoiseTools.hpp +++ b/include/Nazara/Noise/NoiseTools.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Perlin.hpp b/include/Nazara/Noise/Perlin.hpp index 781d03148..64211c4e4 100644 --- a/include/Nazara/Noise/Perlin.hpp +++ b/include/Nazara/Noise/Perlin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Simplex.hpp b/include/Nazara/Noise/Simplex.hpp index 4f33c24ff..2b6309671 100644 --- a/include/Nazara/Noise/Simplex.hpp +++ b/include/Nazara/Noise/Simplex.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Worley.hpp b/include/Nazara/Noise/Worley.hpp index 6b9f21f73..1b820e513 100644 --- a/include/Nazara/Noise/Worley.hpp +++ b/include/Nazara/Noise/Worley.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics2D/Collider2D.hpp b/include/Nazara/Physics2D/Collider2D.hpp index 7bc1c7618..b09e8781f 100644 --- a/include/Nazara/Physics2D/Collider2D.hpp +++ b/include/Nazara/Physics2D/Collider2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -35,15 +35,28 @@ namespace Nz friend RigidBody2D; public: - Collider2D() = default; + inline Collider2D(); Collider2D(const Collider2D&) = delete; Collider2D(Collider2D&&) = delete; virtual ~Collider2D(); virtual float ComputeInertialMatrix(float mass) const = 0; + inline Nz::UInt32 GetCategoryMask() const; + inline Nz::UInt32 GetCollisionGroup() const; + inline unsigned int GetCollisionId() const; + inline Nz::UInt32 GetCollisionMask() const; + virtual ColliderType2D GetType() const = 0; + inline bool IsTrigger() const; + + inline void SetCategoryMask(Nz::UInt32 categoryMask); + inline void SetCollisionGroup(Nz::UInt32 groupId); + inline void SetCollisionId(unsigned int typeId); + inline void SetCollisionMask(Nz::UInt32 mask); + inline void SetTrigger(bool trigger); + Collider2D& operator=(const Collider2D&) = delete; Collider2D& operator=(Collider2D&&) = delete; @@ -53,6 +66,15 @@ namespace Nz protected: virtual std::vector CreateShapes(RigidBody2D* body) const = 0; + bool m_trigger; + Nz::UInt32 m_categoryMask; + Nz::UInt32 m_collisionGroup; + unsigned int m_collisionId; + Nz::UInt32 m_collisionMask; + + private: + virtual std::vector GenerateShapes(RigidBody2D* body) const; + static Collider2DLibrary::LibraryMap s_library; }; diff --git a/include/Nazara/Physics2D/Collider2D.inl b/include/Nazara/Physics2D/Collider2D.inl index 5c3909cde..60cf8559f 100644 --- a/include/Nazara/Physics2D/Collider2D.inl +++ b/include/Nazara/Physics2D/Collider2D.inl @@ -1,12 +1,72 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include namespace Nz { + inline Collider2D::Collider2D() : + m_trigger(false), + m_categoryMask(0xFFFFFFFF), + m_collisionGroup(0), + m_collisionId(0), + m_collisionMask(0xFFFFFFFF) + { + } + + inline Nz::UInt32 Collider2D::GetCategoryMask() const + { + return m_categoryMask; + } + + inline Nz::UInt32 Collider2D::GetCollisionGroup() const + { + return m_collisionGroup; + } + + inline unsigned int Collider2D::GetCollisionId() const + { + return m_collisionId; + } + + inline Nz::UInt32 Collider2D::GetCollisionMask() const + { + return m_collisionMask; + } + + inline bool Collider2D::IsTrigger() const + { + return m_trigger; + } + + inline void Collider2D::SetCategoryMask(Nz::UInt32 categoryMask) + { + m_categoryMask = categoryMask; + } + + inline void Collider2D::SetCollisionGroup(Nz::UInt32 groupId) + { + m_collisionGroup = groupId; + } + + inline void Collider2D::SetCollisionId(unsigned int typeId) + { + m_collisionId = typeId; + } + + inline void Collider2D::SetCollisionMask(Nz::UInt32 mask) + { + m_collisionMask = mask; + } + + inline void Collider2D::SetTrigger(bool trigger) + { + m_trigger = trigger; + } + inline const Rectf& BoxCollider2D::GetRect() const { return m_rect; diff --git a/include/Nazara/Physics2D/ConfigCheck.hpp b/include/Nazara/Physics2D/ConfigCheck.hpp index 3b3b90afc..288cfd59a 100644 --- a/include/Nazara/Physics2D/ConfigCheck.hpp +++ b/include/Nazara/Physics2D/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics2D/Debug.hpp b/include/Nazara/Physics2D/Debug.hpp index 729491e7c..d98efc02d 100644 --- a/include/Nazara/Physics2D/Debug.hpp +++ b/include/Nazara/Physics2D/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics2D/DebugOff.hpp b/include/Nazara/Physics2D/DebugOff.hpp index ffbd0a25a..5cedb88f3 100644 --- a/include/Nazara/Physics2D/DebugOff.hpp +++ b/include/Nazara/Physics2D/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics2D/Enums.hpp b/include/Nazara/Physics2D/Enums.hpp index 529af6f6c..86c1411f4 100644 --- a/include/Nazara/Physics2D/Enums.hpp +++ b/include/Nazara/Physics2D/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics2D/PhysWorld2D.hpp b/include/Nazara/Physics2D/PhysWorld2D.hpp index e194f89d2..30a3b1141 100644 --- a/include/Nazara/Physics2D/PhysWorld2D.hpp +++ b/include/Nazara/Physics2D/PhysWorld2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -8,16 +8,32 @@ #define NAZARA_PHYSWORLD2D_HPP #include +#include #include #include +#include +#include +#include +struct cpCollisionHandler; struct cpSpace; namespace Nz { class NAZARA_PHYSICS2D_API PhysWorld2D { + friend RigidBody2D; + + using ContactEndCallback = void(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata); + using ContactPreSolveCallback = bool(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata); + using ContactPostSolveCallback = void(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata); + using ContactStartCallback = bool(*)(PhysWorld2D& world, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata); + public: + struct Callback; + struct NearestQueryResult; + struct RaycastHit; + PhysWorld2D(); PhysWorld2D(const PhysWorld2D&) = delete; PhysWorld2D(PhysWorld2D&&) = delete; ///TODO @@ -27,8 +43,18 @@ namespace Nz cpSpace* GetHandle() const; float GetStepSize() const; + bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr); + bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result); + + bool RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector* hitInfos); + bool RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo = nullptr); + + void RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector* bodies); + + void RegisterCallbacks(unsigned int collisionId, const Callback& callbacks); + void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks); + void SetGravity(const Vector2f& gravity); - void SetSolverModel(unsigned int model); void SetStepSize(float stepSize); void Step(float timestep); @@ -36,7 +62,56 @@ namespace Nz PhysWorld2D& operator=(const PhysWorld2D&) = delete; PhysWorld2D& operator=(PhysWorld2D&&) = delete; ///TODO + struct Callback + { + ContactEndCallback endCallback = nullptr; + ContactPreSolveCallback preSolveCallback = nullptr; + ContactPostSolveCallback postSolveCallback = nullptr; + ContactStartCallback startCallback = nullptr; + void* userdata; + }; + + struct NearestQueryResult + { + Nz::RigidBody2D* nearestBody; + Nz::Vector2f closestPoint; + Nz::Vector2f fraction; + float distance; + }; + + struct RaycastHit + { + Nz::RigidBody2D* nearestBody; + Nz::Vector2f hitPos; + Nz::Vector2f hitNormal; + float fraction; + }; + + NazaraSignal(OnPhysWorld2DPreStep, const PhysWorld2D* /*physWorld*/); + NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/); + private: + void InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks); + + using PostStep = std::function; + + void OnRigidBodyMoved(RigidBody2D* oldPointer, RigidBody2D* newPointer); + void OnRigidBodyRelease(RigidBody2D* rigidBody); + + void RegisterPostStep(RigidBody2D* rigidBody, PostStep&& func); + + struct PostStepContainer + { + NazaraSlot(RigidBody2D, OnRigidBody2DMove, onMovedSlot); + NazaraSlot(RigidBody2D, OnRigidBody2DRelease, onReleaseSlot); + + std::vector funcs; + }; + + static_assert(std::is_nothrow_move_constructible::value, "PostStepContainer should be noexcept MoveConstructible"); + + std::unordered_map> m_callbacks; + std::unordered_map m_rigidPostSteps; cpSpace* m_handle; float m_stepSize; float m_timestepAccumulator; diff --git a/include/Nazara/Physics2D/Physics2D.hpp b/include/Nazara/Physics2D/Physics2D.hpp index 27fdf3128..3a9f2b731 100644 --- a/include/Nazara/Physics2D/Physics2D.hpp +++ b/include/Nazara/Physics2D/Physics2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics2D/RigidBody2D.hpp b/include/Nazara/Physics2D/RigidBody2D.hpp index 79b7d64bc..9763aba47 100644 --- a/include/Nazara/Physics2D/RigidBody2D.hpp +++ b/include/Nazara/Physics2D/RigidBody2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,8 @@ namespace Nz void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys_Global); void AddForce(const Vector2f& force, const Vector2f& point, CoordSys coordSys = CoordSys_Global); + void AddImpulse(const Vector2f& impulse, CoordSys coordSys = CoordSys_Global); + void AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys = CoordSys_Global); void AddTorque(float torque); Rectf GetAABB() const; @@ -43,6 +46,7 @@ namespace Nz float GetMass() const; Vector2f GetPosition() const; float GetRotation() const; + void* GetUserdata() const; Vector2f GetVelocity() const; bool IsMoveable() const; @@ -54,11 +58,15 @@ namespace Nz void SetMassCenter(const Vector2f& center); void SetPosition(const Vector2f& position); void SetRotation(float rotation); + void SetUserdata(void* ud); void SetVelocity(const Vector2f& velocity); RigidBody2D& operator=(const RigidBody2D& object); RigidBody2D& operator=(RigidBody2D&& object); + NazaraSignal(OnRigidBody2DMove, RigidBody2D* /*oldPointer*/, RigidBody2D* /*newPointer*/); + NazaraSignal(OnRigidBody2DRelease, RigidBody2D* /*rigidBody*/); + private: void Create(float mass = 1.f, float moment = 1.f); void Destroy(); @@ -66,6 +74,7 @@ namespace Nz std::vector m_shapes; Collider2DRef m_geom; cpBody* m_handle; + void* m_userData; PhysWorld2D* m_world; float m_gravityFactor; float m_mass; diff --git a/include/Nazara/Physics3D/Collider3D.hpp b/include/Nazara/Physics3D/Collider3D.hpp index 89e0a4879..13bf32c2f 100644 --- a/include/Nazara/Physics3D/Collider3D.hpp +++ b/include/Nazara/Physics3D/Collider3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/Collider3D.inl b/include/Nazara/Physics3D/Collider3D.inl index aeb7073d8..3ded7d289 100644 --- a/include/Nazara/Physics3D/Collider3D.inl +++ b/include/Nazara/Physics3D/Collider3D.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/ConfigCheck.hpp b/include/Nazara/Physics3D/ConfigCheck.hpp index 012cc426c..7b882ef42 100644 --- a/include/Nazara/Physics3D/ConfigCheck.hpp +++ b/include/Nazara/Physics3D/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/Debug.hpp b/include/Nazara/Physics3D/Debug.hpp index ef111fb96..506b3a773 100644 --- a/include/Nazara/Physics3D/Debug.hpp +++ b/include/Nazara/Physics3D/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/DebugOff.hpp b/include/Nazara/Physics3D/DebugOff.hpp index b8b84c240..9804c567d 100644 --- a/include/Nazara/Physics3D/DebugOff.hpp +++ b/include/Nazara/Physics3D/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/Enums.hpp b/include/Nazara/Physics3D/Enums.hpp index b01c9bb83..12c754899 100644 --- a/include/Nazara/Physics3D/Enums.hpp +++ b/include/Nazara/Physics3D/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/PhysWorld3D.hpp b/include/Nazara/Physics3D/PhysWorld3D.hpp index ea84aa931..633be2b61 100644 --- a/include/Nazara/Physics3D/PhysWorld3D.hpp +++ b/include/Nazara/Physics3D/PhysWorld3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/Physics3D.hpp b/include/Nazara/Physics3D/Physics3D.hpp index 949301002..b0d6f69f5 100644 --- a/include/Nazara/Physics3D/Physics3D.hpp +++ b/include/Nazara/Physics3D/Physics3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics3D/RigidBody3D.hpp b/include/Nazara/Physics3D/RigidBody3D.hpp index d895e9040..502fd21a7 100644 --- a/include/Nazara/Physics3D/RigidBody3D.hpp +++ b/include/Nazara/Physics3D/RigidBody3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Prerequesites.hpp b/include/Nazara/Prerequesites.hpp index 13a044f68..0ac6b0fae 100644 --- a/include/Nazara/Prerequesites.hpp +++ b/include/Nazara/Prerequesites.hpp @@ -77,8 +77,8 @@ // Nazara version macro #define NAZARA_VERSION_MAJOR 0 -#define NAZARA_VERSION_MINOR 2 -#define NAZARA_VERSION_PATCH 1 +#define NAZARA_VERSION_MINOR 3 +#define NAZARA_VERSION_PATCH 0 #include diff --git a/include/Nazara/Renderer/ConfigCheck.hpp b/include/Nazara/Renderer/ConfigCheck.hpp index 71cc3d5eb..d8e677789 100644 --- a/include/Nazara/Renderer/ConfigCheck.hpp +++ b/include/Nazara/Renderer/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Debug.hpp b/include/Nazara/Renderer/Debug.hpp index ef0e73147..22444ba98 100644 --- a/include/Nazara/Renderer/Debug.hpp +++ b/include/Nazara/Renderer/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/DebugOff.hpp b/include/Nazara/Renderer/DebugOff.hpp index b20650b99..ecc9a1b92 100644 --- a/include/Nazara/Renderer/DebugOff.hpp +++ b/include/Nazara/Renderer/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index b610d43b3..2621081cd 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderPipeline.hpp b/include/Nazara/Renderer/RenderPipeline.hpp new file mode 100644 index 000000000..846cfb4af --- /dev/null +++ b/include/Nazara/Renderer/RenderPipeline.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RENDERPIPELINE_HPP +#define NAZARA_RENDERPIPELINE_HPP + +#include +#include +#include + +namespace Nz +{ + struct RenderPipelineInfo : RenderStates + { + ShaderConstRef shader; + }; + + class RenderPipeline + { + public: + inline RenderPipeline(); + inline ~RenderPipeline(); + + inline bool Create(const RenderPipelineInfo& pipelineInfo); + inline void Destroy(); + + inline const RenderPipelineInfo& GetInfo() const; + + inline bool IsValid() const; + + private: + RenderPipelineInfo m_pipelineInfo; + bool m_valid; + }; +} + +#include + +#endif // NAZARA_RENDERPIPELINE_HPP diff --git a/include/Nazara/Renderer/RenderPipeline.inl b/include/Nazara/Renderer/RenderPipeline.inl new file mode 100644 index 000000000..2a1aef815 --- /dev/null +++ b/include/Nazara/Renderer/RenderPipeline.inl @@ -0,0 +1,48 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + inline RenderPipeline::RenderPipeline() : + m_valid(false) + { + } + + inline RenderPipeline::~RenderPipeline() + { + } + + inline bool RenderPipeline::Create(const RenderPipelineInfo& pipelineInfo) + { + NazaraAssert(pipelineInfo.shader, "Invalid shader"); + + m_pipelineInfo = pipelineInfo; + m_valid = true; + + return true; + } + + inline void RenderPipeline::Destroy() + { + m_valid = false; + } + + inline const RenderPipelineInfo& RenderPipeline::GetInfo() const + { + NazaraAssert(m_valid, "Invalid pipeline info"); + + return m_pipelineInfo; + } + + inline bool RenderPipeline::IsValid() const + { + return m_valid; + } +} + +#include diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index fc4d10eeb..dee9db808 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderStates.inl b/include/Nazara/Renderer/RenderStates.inl index 525491162..7f976ff13 100644 --- a/include/Nazara/Renderer/RenderStates.inl +++ b/include/Nazara/Renderer/RenderStates.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index a92ed3352..8f2b494e9 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 195b9b40a..3b88ad505 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -23,7 +23,7 @@ namespace Nz public: Renderer() = delete; ~Renderer() = delete; - + static inline RendererImpl* GetRendererImpl(); static bool Initialize(); diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 6d52beb6f..7c5f9ab6e 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Utility.hpp b/include/Nazara/Utility.hpp index 3734b919e..fbb100476 100644 --- a/include/Nazara/Utility.hpp +++ b/include/Nazara/Utility.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 16d09235f..49565cdf2 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/AbstractBuffer.hpp b/include/Nazara/Utility/AbstractBuffer.hpp index ff264d6b9..a0f183218 100644 --- a/include/Nazara/Utility/AbstractBuffer.hpp +++ b/include/Nazara/Utility/AbstractBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/AbstractImage.hpp b/include/Nazara/Utility/AbstractImage.hpp index ffeacbca4..7bba13de1 100644 --- a/include/Nazara/Utility/AbstractImage.hpp +++ b/include/Nazara/Utility/AbstractImage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/AbstractImage.inl b/include/Nazara/Utility/AbstractImage.inl index b3e5fc417..fe456669f 100644 --- a/include/Nazara/Utility/AbstractImage.inl +++ b/include/Nazara/Utility/AbstractImage.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/AbstractTextDrawer.hpp b/include/Nazara/Utility/AbstractTextDrawer.hpp index dd05e5af6..becb9dac6 100644 --- a/include/Nazara/Utility/AbstractTextDrawer.hpp +++ b/include/Nazara/Utility/AbstractTextDrawer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 70c4cdc60..1652976c3 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 2ab1f2baa..7f7595bbd 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Animation.inl b/include/Nazara/Utility/Animation.inl index 0ae58c0f4..d56733c57 100644 --- a/include/Nazara/Utility/Animation.inl +++ b/include/Nazara/Utility/Animation.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 3655de53c..526a153e4 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Buffer.inl b/include/Nazara/Utility/Buffer.inl index df54a3987..afeef1624 100644 --- a/include/Nazara/Utility/Buffer.inl +++ b/include/Nazara/Utility/Buffer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/BufferMapper.hpp b/include/Nazara/Utility/BufferMapper.hpp index b34c41c73..4f80528fd 100644 --- a/include/Nazara/Utility/BufferMapper.hpp +++ b/include/Nazara/Utility/BufferMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/BufferMapper.inl b/include/Nazara/Utility/BufferMapper.inl index 1284ba26d..4b7b8be35 100644 --- a/include/Nazara/Utility/BufferMapper.inl +++ b/include/Nazara/Utility/BufferMapper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/ConfigCheck.hpp b/include/Nazara/Utility/ConfigCheck.hpp index 01d224a7a..bbfd6ea66 100644 --- a/include/Nazara/Utility/ConfigCheck.hpp +++ b/include/Nazara/Utility/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/CubemapParams.hpp b/include/Nazara/Utility/CubemapParams.hpp index 0f9e6eba4..6153eb06d 100644 --- a/include/Nazara/Utility/CubemapParams.hpp +++ b/include/Nazara/Utility/CubemapParams.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Cursor.hpp b/include/Nazara/Utility/Cursor.hpp index b45fc6a1b..870b17b55 100644 --- a/include/Nazara/Utility/Cursor.hpp +++ b/include/Nazara/Utility/Cursor.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -8,31 +8,64 @@ #define NAZARA_CURSOR_HPP #include +#include #include #include +#include +#include namespace Nz { class CursorImpl; - class Image; - class NAZARA_UTILITY_API Cursor + class Cursor; + + using CursorConstRef = ObjectRef; + using CursorRef = ObjectRef; + + class NAZARA_UTILITY_API Cursor : public RefCounted { + friend class Utility; friend class WindowImpl; public: - Cursor(); - ~Cursor(); + inline Cursor(); + inline Cursor(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder); + Cursor(const Cursor&) = delete; + Cursor(Cursor&&) = delete; + inline ~Cursor(); + + bool Create(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder); - bool Create(const Image& cursor, int hotSpotX = 0, int hotSpotY = 0); - bool Create(const Image& cursor, const Vector2i& hotSpot); void Destroy(); - bool IsValid() const; + inline const Image& GetImage() const; + inline SystemCursor GetSystemCursor() const; + + inline bool IsValid() const; + + Cursor& operator=(const Cursor&) = delete; + Cursor& operator=(Cursor&&) = delete; + + static inline Cursor* Get(SystemCursor cursor); + template static CursorRef New(Args&&... args); private: + inline explicit Cursor(SystemCursor systemCursor); + + bool Create(SystemCursor cursor); + + static bool Initialize(); + static void Uninitialize(); + + Image m_cursorImage; + SystemCursor m_systemCursor; CursorImpl* m_impl; + + static std::array s_systemCursors; }; } +#include + #endif // NAZARA_CURSOR_HPP diff --git a/include/Nazara/Utility/Cursor.inl b/include/Nazara/Utility/Cursor.inl new file mode 100644 index 000000000..58d15bdec --- /dev/null +++ b/include/Nazara/Utility/Cursor.inl @@ -0,0 +1,69 @@ +// Copyright (C) 2017 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 + +namespace Nz +{ + inline Cursor::Cursor() : + m_impl(nullptr) + { + } + + inline Cursor::Cursor(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(cursor, hotSpot, placeholder); + } + + inline Cursor* Cursor::Get(SystemCursor cursor) + { + return &s_systemCursors[cursor]; + } + + inline Cursor::Cursor(SystemCursor systemCursor) : + Cursor() + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(systemCursor); + } + + inline Cursor::~Cursor() + { + Destroy(); + } + + inline const Image& Cursor::GetImage() const + { + NazaraAssert(IsValid(), "Invalid cursor"); + NazaraAssert(m_cursorImage.IsValid(), "System cursors have no image"); + + return m_cursorImage; + } + + inline SystemCursor Cursor::GetSystemCursor() const + { + NazaraAssert(IsValid(), "Invalid cursor"); + + return m_systemCursor; + } + + inline bool Cursor::IsValid() const + { + return m_impl != nullptr; + } + + template + CursorRef Cursor::New(Args&&... args) + { + std::unique_ptr object(new Cursor(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } +} + +#include diff --git a/include/Nazara/Utility/CursorController.hpp b/include/Nazara/Utility/CursorController.hpp new file mode 100644 index 000000000..0c2943356 --- /dev/null +++ b/include/Nazara/Utility/CursorController.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2017 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_CURSORCONTROLLER_HPP +#define NAZARA_CURSORCONTROLLER_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class CursorController; + + using CursorControllerHandle = ObjectHandle; + + class CursorController : public HandledObject + { + public: + CursorController() = default; + CursorController(const CursorController&) = delete; + CursorController(CursorController&&) = default; + ~CursorController() = default; + + inline void UpdateCursor(const CursorRef& cursor); + + CursorController& operator=(const CursorController&) = delete; + CursorController& operator=(CursorController&&) = default; + + NazaraSignal(OnCursorUpdated, const CursorController* /*cursorController*/, const CursorRef& /*cursor*/); + }; +} + +#include + +#endif // NAZARA_CURSORCONTROLLER_HPP diff --git a/include/Nazara/Utility/CursorController.inl b/include/Nazara/Utility/CursorController.inl new file mode 100644 index 000000000..b1f54d05a --- /dev/null +++ b/include/Nazara/Utility/CursorController.inl @@ -0,0 +1,16 @@ +// Copyright (C) 2017 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 +{ + inline void CursorController::UpdateCursor(const CursorRef& cursor) + { + OnCursorUpdated(this, cursor); + } +} + +#include diff --git a/include/Nazara/Utility/Debug.hpp b/include/Nazara/Utility/Debug.hpp index 85319685a..2041a7363 100644 --- a/include/Nazara/Utility/Debug.hpp +++ b/include/Nazara/Utility/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/DebugOff.hpp b/include/Nazara/Utility/DebugOff.hpp index 5cb9a0750..621ac2c38 100644 --- a/include/Nazara/Utility/DebugOff.hpp +++ b/include/Nazara/Utility/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index fd9001d44..d72b90d6c 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -307,6 +307,30 @@ namespace Nz SamplerWrap_Max = SamplerWrap_Repeat }; + enum SystemCursor + { + SystemCursor_Crosshair, + SystemCursor_Default, + SystemCursor_Hand, + SystemCursor_Help, + SystemCursor_Move, + SystemCursor_None, + SystemCursor_Pointer, + SystemCursor_Progress, + SystemCursor_ResizeE, + SystemCursor_ResizeN, + SystemCursor_ResizeNE, + SystemCursor_ResizeNW, + SystemCursor_ResizeS, + SystemCursor_ResizeSE, + SystemCursor_ResizeSW, + SystemCursor_ResizeW, + SystemCursor_Text, + SystemCursor_Wait, + + SystemCursor_Max = SystemCursor_Wait + }; + enum StencilOperation { StencilOperation_Decrement, @@ -393,31 +417,6 @@ namespace Nz VertexLayout_Max = VertexLayout_Matrix4 }; - enum WindowCursor - { - WindowCursor_None, - WindowCursor_Default, - - WindowCursor_Crosshair, - WindowCursor_Hand, - WindowCursor_Help, - WindowCursor_Move, - WindowCursor_Pointer, - WindowCursor_Progress, - WindowCursor_ResizeE, - WindowCursor_ResizeN, - WindowCursor_ResizeNE, - WindowCursor_ResizeNW, - WindowCursor_ResizeS, - WindowCursor_ResizeSE, - WindowCursor_ResizeSW, - WindowCursor_ResizeW, - WindowCursor_Text, - WindowCursor_Wait, - - WindowCursor_Max = WindowCursor_Wait - }; - enum WindowEventType { WindowEventType_GainedFocus, diff --git a/include/Nazara/Utility/Event.hpp b/include/Nazara/Utility/Event.hpp index c5535abff..b67eedc0c 100644 --- a/include/Nazara/Utility/Event.hpp +++ b/include/Nazara/Utility/Event.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/EventHandler.hpp b/include/Nazara/Utility/EventHandler.hpp index 5bc47bdea..78cba94bc 100644 --- a/include/Nazara/Utility/EventHandler.hpp +++ b/include/Nazara/Utility/EventHandler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -8,13 +8,19 @@ #define NAZARA_EVENTHANDLER_HPP #include +#include +#include #include #include #include namespace Nz { - class EventHandler + class EventHandler; + + using EventHandlerHandle = ObjectHandle; + + class EventHandler : public HandledObject { public: EventHandler() = default; diff --git a/include/Nazara/Utility/EventHandler.inl b/include/Nazara/Utility/EventHandler.inl index 719ffddcb..39191300d 100644 --- a/include/Nazara/Utility/EventHandler.inl +++ b/include/Nazara/Utility/EventHandler.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -8,7 +8,8 @@ namespace Nz { - inline EventHandler::EventHandler(const EventHandler&) + inline EventHandler::EventHandler(const EventHandler& other) : + HandledObject(other) { } diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 9a226d91e..643120aab 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Font.inl b/include/Nazara/Utility/Font.inl index 241915a3e..efe2a4adc 100644 --- a/include/Nazara/Utility/Font.inl +++ b/include/Nazara/Utility/Font.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/FontData.hpp b/include/Nazara/Utility/FontData.hpp index 78da99792..5b0868e3c 100644 --- a/include/Nazara/Utility/FontData.hpp +++ b/include/Nazara/Utility/FontData.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/FontGlyph.hpp b/include/Nazara/Utility/FontGlyph.hpp index 2ea194116..ea673e178 100644 --- a/include/Nazara/Utility/FontGlyph.hpp +++ b/include/Nazara/Utility/FontGlyph.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Formats/MD5AnimParser.hpp b/include/Nazara/Utility/Formats/MD5AnimParser.hpp index 3a9e2163d..d62cdaae8 100644 --- a/include/Nazara/Utility/Formats/MD5AnimParser.hpp +++ b/include/Nazara/Utility/Formats/MD5AnimParser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Formats/MD5MeshParser.hpp b/include/Nazara/Utility/Formats/MD5MeshParser.hpp index b515c1226..dce6bcc72 100644 --- a/include/Nazara/Utility/Formats/MD5MeshParser.hpp +++ b/include/Nazara/Utility/Formats/MD5MeshParser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Formats/MTLParser.hpp b/include/Nazara/Utility/Formats/MTLParser.hpp index 708e30685..ec50f2137 100644 --- a/include/Nazara/Utility/Formats/MTLParser.hpp +++ b/include/Nazara/Utility/Formats/MTLParser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Formats/MTLParser.inl b/include/Nazara/Utility/Formats/MTLParser.inl index 0f8cd4f66..00e9e8b89 100644 --- a/include/Nazara/Utility/Formats/MTLParser.inl +++ b/include/Nazara/Utility/Formats/MTLParser.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 82c1220bf..c01f7724a 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index 41e794f82..4b780672b 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index 318b92d6b..739328dc6 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Icon.hpp b/include/Nazara/Utility/Icon.hpp index 4f0397faf..db93e9495 100644 --- a/include/Nazara/Utility/Icon.hpp +++ b/include/Nazara/Utility/Icon.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -8,6 +8,7 @@ #define NAZARA_ICON_HPP #include +#include #include #include @@ -16,22 +17,31 @@ namespace Nz class Image; class IconImpl; - class NAZARA_UTILITY_API Icon + class Icon; + + using IconRef = ObjectRef; + + class NAZARA_UTILITY_API Icon : public RefCounted { friend class WindowImpl; public: - Icon(); - ~Icon(); + inline Icon(); + inline explicit Icon(const Image& icon); + inline ~Icon(); bool Create(const Image& icon); void Destroy(); - bool IsValid() const; + inline bool IsValid() const; + + template static IconRef New(Args&&... args); private: IconImpl* m_impl; }; } +#include + #endif // NAZARA_ICON_HPP diff --git a/include/Nazara/Utility/Icon.inl b/include/Nazara/Utility/Icon.inl new file mode 100644 index 000000000..5c6b60068 --- /dev/null +++ b/include/Nazara/Utility/Icon.inl @@ -0,0 +1,42 @@ +// Copyright (C) 2017 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 + +namespace Nz +{ + Icon::Icon() : + m_impl(nullptr) + { + } + + inline Icon::Icon(const Image& icon) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(icon); + } + + Icon::~Icon() + { + Destroy(); + } + + bool Icon::IsValid() const + { + return m_impl != nullptr; + } + + template + IconRef Icon::New(Args&&... args) + { + std::unique_ptr object(new Icon(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } +} + +#include diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index e1712aed1..cbae97f9a 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -78,18 +78,18 @@ namespace Nz bool FlipVertically(); const UInt8* GetConstPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, UInt8 level = 0) const; - unsigned int GetDepth(UInt8 level = 0) const; - PixelFormatType GetFormat() const; - unsigned int GetHeight(UInt8 level = 0) const; - UInt8 GetLevelCount() const; - UInt8 GetMaxLevel() const; - std::size_t GetMemoryUsage() const; - std::size_t GetMemoryUsage(UInt8 level) const; + unsigned int GetDepth(UInt8 level = 0) const override; + PixelFormatType GetFormat() const override; + unsigned int GetHeight(UInt8 level = 0) const override; + UInt8 GetLevelCount() const override; + UInt8 GetMaxLevel() const override; + std::size_t GetMemoryUsage() const override; + std::size_t GetMemoryUsage(UInt8 level) const override; Color GetPixelColor(unsigned int x, unsigned int y = 0, unsigned int z = 0) const; UInt8* GetPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, UInt8 level = 0); - Vector3ui GetSize(UInt8 level = 0) const; - ImageType GetType() const; - unsigned int GetWidth(UInt8 level = 0) const; + Vector3ui GetSize(UInt8 level = 0) const override; + ImageType GetType() const override; + unsigned int GetWidth(UInt8 level = 0) const override; bool HasAlpha() const; @@ -126,9 +126,9 @@ namespace Nz void SetLevelCount(UInt8 levelCount); bool SetPixelColor(const Color& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); - bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); - bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); - bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); + bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override; + bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override; + bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override; Image& operator=(const Image& image); diff --git a/include/Nazara/Utility/Image.inl b/include/Nazara/Utility/Image.inl index 5cb8ef42f..b59a2629b 100644 --- a/include/Nazara/Utility/Image.inl +++ b/include/Nazara/Utility/Image.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index 75010bdc0..2c66bc6ed 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index f598c5291..0ae918db7 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -45,7 +45,7 @@ namespace Nz inline bool IndexBuffer::IsValid() const { - return m_buffer; + return m_buffer.IsValid(); } inline void* IndexBuffer::Map(BufferAccess access, UInt32 startIndex, UInt32 length) diff --git a/include/Nazara/Utility/IndexIterator.hpp b/include/Nazara/Utility/IndexIterator.hpp index 7620d3b28..63f9d96b9 100644 --- a/include/Nazara/Utility/IndexIterator.hpp +++ b/include/Nazara/Utility/IndexIterator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -26,15 +26,15 @@ namespace Nz Reference operator*() const; - Reference operator[](unsigned int index) const; + Reference operator[](std::size_t index) const; IndexIterator& operator=(const IndexIterator& iterator); - IndexIterator operator+(unsigned int indexCount) const; - IndexIterator operator-(unsigned int indexCount) const; + IndexIterator operator+(std::size_t indexCount) const; + IndexIterator operator-(std::size_t indexCount) const; - IndexIterator& operator+=(unsigned int indexCount); - IndexIterator& operator-=(unsigned int indexCount); + IndexIterator& operator+=(std::size_t indexCount); + IndexIterator& operator-=(std::size_t indexCount); IndexIterator& operator++(); IndexIterator operator++(int); @@ -50,10 +50,10 @@ namespace Nz friend bool operator>=(const IndexIterator& lhs, const IndexIterator& rhs); private: - IndexIterator(IndexMapper* mapper, unsigned int index); + IndexIterator(IndexMapper* mapper, std::size_t index); IndexMapper* m_mapper; - unsigned int m_index; + std::size_t m_index; }; class IndexIterator::Reference @@ -70,10 +70,10 @@ namespace Nz operator UInt32() const; private: - Reference(IndexMapper* mapper, unsigned int index); + Reference(IndexMapper* mapper, std::size_t index); IndexMapper* m_mapper; - unsigned int m_index; + std::size_t m_index; }; } diff --git a/include/Nazara/Utility/IndexIterator.inl b/include/Nazara/Utility/IndexIterator.inl index f0d3d5a95..0398059f6 100644 --- a/include/Nazara/Utility/IndexIterator.inl +++ b/include/Nazara/Utility/IndexIterator.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -20,7 +20,7 @@ namespace Nz { } - inline IndexIterator::IndexIterator(IndexMapper* mapper, unsigned int index) : + inline IndexIterator::IndexIterator(IndexMapper* mapper, std::size_t index) : m_mapper(mapper), m_index(index) { @@ -31,7 +31,7 @@ namespace Nz return Reference(m_mapper, m_index); } - inline IndexIterator::Reference IndexIterator::operator[](unsigned int index) const + inline IndexIterator::Reference IndexIterator::operator[](std::size_t index) const { return Reference(m_mapper, m_index+index); } @@ -44,24 +44,24 @@ namespace Nz return *this; } - inline IndexIterator IndexIterator::operator+(unsigned int indexCount) const + inline IndexIterator IndexIterator::operator+(std::size_t indexCount) const { return IndexIterator(m_mapper, m_index + indexCount); } - inline IndexIterator IndexIterator::operator-(unsigned int indexCount) const + inline IndexIterator IndexIterator::operator-(std::size_t indexCount) const { return IndexIterator(m_mapper, m_index - indexCount); } - inline IndexIterator& IndexIterator::operator+=(unsigned int indexCount) + inline IndexIterator& IndexIterator::operator+=(std::size_t indexCount) { m_index += indexCount; return *this; } - inline IndexIterator& IndexIterator::operator-=(unsigned int indexCount) + inline IndexIterator& IndexIterator::operator-=(std::size_t indexCount) { m_index += indexCount; @@ -133,7 +133,7 @@ namespace Nz /**************************IndexIterator::Reference*************************/ - inline IndexIterator::Reference::Reference(IndexMapper* mapper, unsigned int index) : + inline IndexIterator::Reference::Reference(IndexMapper* mapper, std::size_t index) : m_mapper(mapper), m_index(index) { @@ -148,7 +148,7 @@ namespace Nz inline IndexIterator::Reference& IndexIterator::Reference::operator=(const IndexIterator::Reference& reference) { - m_mapper->Set(m_index, reference); // Conversion implicite en UInt32 + m_mapper->Set(m_index, reference); // Implicit conversion to UInt32 return *this; } diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index 7f632f196..b18e8989f 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -17,9 +17,6 @@ namespace Nz class IndexIterator; class SubMesh; - using IndexMapperGetter = UInt32 (*)(const void* buffer, unsigned int i); - using IndexMapperSetter = void (*)(void* buffer, unsigned int i, UInt32 value); - class NAZARA_UTILITY_API IndexMapper { public: @@ -29,11 +26,11 @@ namespace Nz IndexMapper(const SubMesh* subMesh, BufferAccess access = BufferAccess_ReadOnly); ~IndexMapper() = default; - UInt32 Get(unsigned int i) const; + UInt32 Get(std::size_t i) const; const IndexBuffer* GetBuffer() const; - unsigned int GetIndexCount() const; + std::size_t GetIndexCount() const; - void Set(unsigned int i, UInt32 value); + void Set(std::size_t i, UInt32 value); void Unmap(); @@ -45,10 +42,13 @@ namespace Nz // Méthodes STD private: + using Getter = UInt32(*)(const void* buffer, std::size_t i); + using Setter = void(*)(void* buffer, std::size_t i, UInt32 value); + BufferMapper m_mapper; - IndexMapperGetter m_getter; - IndexMapperSetter m_setter; - unsigned int m_indexCount; + Getter m_getter; + Setter m_setter; + std::size_t m_indexCount; }; } diff --git a/include/Nazara/Utility/Joint.hpp b/include/Nazara/Utility/Joint.hpp index 77227a605..fad4b3d22 100644 --- a/include/Nazara/Utility/Joint.hpp +++ b/include/Nazara/Utility/Joint.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -35,7 +35,7 @@ namespace Nz void SetName(const String& name); private: - void InvalidateNode(); + void InvalidateNode() override; void UpdateSkinningMatrix() const; Matrix4f m_inverseBindMatrix; diff --git a/include/Nazara/Utility/Joystick.hpp b/include/Nazara/Utility/Joystick.hpp index ce84c9473..f80b4b590 100644 --- a/include/Nazara/Utility/Joystick.hpp +++ b/include/Nazara/Utility/Joystick.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Keyboard.hpp b/include/Nazara/Utility/Keyboard.hpp index 8eea51ff5..bfd050d73 100644 --- a/include/Nazara/Utility/Keyboard.hpp +++ b/include/Nazara/Utility/Keyboard.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/MaterialData.hpp b/include/Nazara/Utility/MaterialData.hpp index 0c1e28cdd..c2634d92c 100644 --- a/include/Nazara/Utility/MaterialData.hpp +++ b/include/Nazara/Utility/MaterialData.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 8cbbaf70b..a05f7c9f4 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Mesh.inl b/include/Nazara/Utility/Mesh.inl index 4877e03fe..e63cb389f 100644 --- a/include/Nazara/Utility/Mesh.inl +++ b/include/Nazara/Utility/Mesh.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/MeshData.hpp b/include/Nazara/Utility/MeshData.hpp index e9a3021f6..54b5ca0e7 100644 --- a/include/Nazara/Utility/MeshData.hpp +++ b/include/Nazara/Utility/MeshData.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Mouse.hpp b/include/Nazara/Utility/Mouse.hpp index 47fd7a1e0..552011904 100644 --- a/include/Nazara/Utility/Mouse.hpp +++ b/include/Nazara/Utility/Mouse.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 71ba4d73d..e70732837 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/PixelFormat.hpp b/include/Nazara/Utility/PixelFormat.hpp index 92eecb7f4..f6c3a36a4 100644 --- a/include/Nazara/Utility/PixelFormat.hpp +++ b/include/Nazara/Utility/PixelFormat.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -65,7 +65,7 @@ namespace Nz static inline bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* src, void* dst); static inline bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* start, const void* end, void* dst); - static inline bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst); + static bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst); static inline UInt8 GetBitsPerPixel(PixelFormatType format); static inline PixelFormatContent GetContent(PixelFormatType format); diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 59ad2ab04..4fe75c8b5 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -227,102 +227,6 @@ namespace Nz return true; } - inline bool PixelFormat::Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst) - { - #if NAZARA_UTILITY_SAFE - if (!IsValid(format)) - { - NazaraError("Invalid pixel format"); - return false; - } - #endif - - auto it = s_flipFunctions[flipping].find(format); - if (it != s_flipFunctions[flipping].end()) - it->second(width, height, depth, reinterpret_cast(src), reinterpret_cast(dst)); - else - { - // Flipping générique - - #if NAZARA_UTILITY_SAFE - if (IsCompressed(format)) - { - NazaraError("No function to flip compressed format"); - return false; - } - #endif - - UInt8 bpp = GetBytesPerPixel(format); - unsigned int lineStride = width*bpp; - switch (flipping) - { - case PixelFlipping_Horizontally: - { - if (src == dst) - { - for (unsigned int z = 0; z < depth; ++z) - { - UInt8* ptr = reinterpret_cast(dst) + width*height*z; - for (unsigned int y = 0; y < height/2; ++y) - std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]); - } - } - else - { - for (unsigned int z = 0; z < depth; ++z) - { - const UInt8* srcPtr = reinterpret_cast(src); - UInt8* dstPtr = reinterpret_cast(dst) + (width-1)*height*depth*bpp; - for (unsigned int y = 0; y < height; ++y) - { - std::memcpy(dstPtr, srcPtr, lineStride); - - srcPtr += lineStride; - dstPtr -= lineStride; - } - } - } - break; - } - - case PixelFlipping_Vertically: - { - if (src == dst) - { - for (unsigned int z = 0; z < depth; ++z) - { - UInt8* ptr = reinterpret_cast(dst) + width*height*z; - for (unsigned int y = 0; y < height; ++y) - { - for (unsigned int x = 0; x < width/2; ++x) - std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]); - - ptr += lineStride; - } - } - } - else - { - for (unsigned int z = 0; z < depth; ++z) - { - UInt8* ptr = reinterpret_cast(dst) + width*height*z; - for (unsigned int y = 0; y < height; ++y) - { - for (unsigned int x = 0; x < width; ++x) - std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp); - - ptr += lineStride; - } - } - } - break; - } - } - } - - return true; - } - inline UInt8 PixelFormat::GetBitsPerPixel(PixelFormatType format) { return s_pixelFormatInfos[format].bitsPerPixel; diff --git a/include/Nazara/Utility/Sequence.hpp b/include/Nazara/Utility/Sequence.hpp index b8549a4bf..1f729e5e4 100644 --- a/include/Nazara/Utility/Sequence.hpp +++ b/include/Nazara/Utility/Sequence.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 7c2db6c20..90b501690 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index 616fb3dec..d67210c74 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -29,13 +29,13 @@ namespace Nz void Destroy(); const Boxf& GetAABB() const override; - AnimationType GetAnimationType() const final; + AnimationType GetAnimationType() const final override; const IndexBuffer* GetIndexBuffer() const override; VertexBuffer* GetVertexBuffer(); const VertexBuffer* GetVertexBuffer() const; unsigned int GetVertexCount() const override; - bool IsAnimated() const final; + bool IsAnimated() const final override; bool IsValid() const; void SetAABB(const Boxf& aabb); diff --git a/include/Nazara/Utility/SkeletalMesh.inl b/include/Nazara/Utility/SkeletalMesh.inl index 69119dc87..561e906e9 100644 --- a/include/Nazara/Utility/SkeletalMesh.inl +++ b/include/Nazara/Utility/SkeletalMesh.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 8312f967f..0ed6c6691 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Skeleton.inl b/include/Nazara/Utility/Skeleton.inl index 4c0ef4546..ece3fbf98 100644 --- a/include/Nazara/Utility/Skeleton.inl +++ b/include/Nazara/Utility/Skeleton.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/SoftwareBuffer.hpp b/include/Nazara/Utility/SoftwareBuffer.hpp index 1bd4eb3db..f199a9a8e 100644 --- a/include/Nazara/Utility/SoftwareBuffer.hpp +++ b/include/Nazara/Utility/SoftwareBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index d5fe8907d..125af6301 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -32,13 +32,13 @@ namespace Nz bool GenerateAABB(); const Boxf& GetAABB() const override; - AnimationType GetAnimationType() const final; + AnimationType GetAnimationType() const final override; const IndexBuffer* GetIndexBuffer() const override; VertexBuffer* GetVertexBuffer(); const VertexBuffer* GetVertexBuffer() const; unsigned int GetVertexCount() const override; - bool IsAnimated() const final; + bool IsAnimated() const final override; bool IsValid() const; void SetAABB(const Boxf& aabb); diff --git a/include/Nazara/Utility/StaticMesh.inl b/include/Nazara/Utility/StaticMesh.inl index 06afcec95..efe6ffd12 100644 --- a/include/Nazara/Utility/StaticMesh.inl +++ b/include/Nazara/Utility/StaticMesh.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index 525930e0b..d9d5cd2bf 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/TriangleIterator.hpp b/include/Nazara/Utility/TriangleIterator.hpp index 32c9ceb07..8bf17a2eb 100644 --- a/include/Nazara/Utility/TriangleIterator.hpp +++ b/include/Nazara/Utility/TriangleIterator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -24,7 +24,7 @@ namespace Nz bool Advance(); - UInt32 operator[](unsigned int i) const; + UInt32 operator[](std::size_t i) const; void Unmap(); @@ -32,8 +32,8 @@ namespace Nz PrimitiveMode m_primitiveMode; UInt32 m_triangleIndices[3]; IndexMapper m_indexMapper; - unsigned int m_currentIndex; - unsigned int m_indexCount; + std::size_t m_currentIndex; + std::size_t m_indexCount; }; } diff --git a/include/Nazara/Utility/Utility.hpp b/include/Nazara/Utility/Utility.hpp index 31ec543ee..d78121f2c 100644 --- a/include/Nazara/Utility/Utility.hpp +++ b/include/Nazara/Utility/Utility.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 12614355e..8f5b608e2 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VertexBuffer.inl b/include/Nazara/Utility/VertexBuffer.inl index 45dc75ea7..09f701d12 100644 --- a/include/Nazara/Utility/VertexBuffer.inl +++ b/include/Nazara/Utility/VertexBuffer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -39,7 +39,7 @@ namespace Nz inline bool VertexBuffer::IsValid() const { - return m_buffer && m_vertexDeclaration; + return m_buffer.IsValid() && m_vertexDeclaration.IsValid(); } template diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 8c1e4b55a..594f1b5f0 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VertexDeclaration.inl b/include/Nazara/Utility/VertexDeclaration.inl index beed900d5..26cd39736 100644 --- a/include/Nazara/Utility/VertexDeclaration.inl +++ b/include/Nazara/Utility/VertexDeclaration.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index e18250d7c..486d000fd 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index 4a155bfbd..6892f9091 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VertexStruct.hpp b/include/Nazara/Utility/VertexStruct.hpp index d9fa1d050..2a811722e 100644 --- a/include/Nazara/Utility/VertexStruct.hpp +++ b/include/Nazara/Utility/VertexStruct.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/VideoMode.hpp b/include/Nazara/Utility/VideoMode.hpp index 3c2243817..4d6a77768 100644 --- a/include/Nazara/Utility/VideoMode.hpp +++ b/include/Nazara/Utility/VideoMode.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index 5ecabd8dd..32487370a 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -15,17 +15,18 @@ #include #include #include +#include +#include #include #include +#include #include #include #include namespace Nz { - class Cursor; class Image; - class Icon; class WindowImpl; class NAZARA_UTILITY_API Window @@ -35,7 +36,7 @@ namespace Nz friend class Utility; public: - inline Window(); + Window(); inline Window(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default); inline Window(WindowHandle handle); Window(const Window&) = delete; @@ -57,7 +58,9 @@ namespace Nz void EnableKeyRepeat(bool enable); void EnableSmoothScrolling(bool enable); - EventHandler& GetEventHandler(); + inline const CursorRef& GetCursor() const; + inline CursorController& GetCursorController(); + inline EventHandler& GetEventHandler(); WindowHandle GetHandle() const; unsigned int GetHeight() const; Vector2i GetPosition() const; @@ -79,11 +82,11 @@ namespace Nz void ProcessEvents(bool block = false); - void SetCursor(WindowCursor cursor); - void SetCursor(const Cursor& cursor); + void SetCursor(CursorRef cursor); + inline void SetCursor(SystemCursor systemCursor); void SetEventListener(bool listener); void SetFocus(); - void SetIcon(const Icon& icon); + void SetIcon(IconRef icon); void SetMaximumSize(const Vector2i& maxSize); void SetMaximumSize(int width, int height); void SetMinimumSize(const Vector2i& minSize); @@ -120,7 +123,10 @@ namespace Nz std::queue m_events; std::vector m_pendingEvents; ConditionVariable m_eventCondition; + CursorController m_cursorController; + CursorRef m_cursor; EventHandler m_eventHandler; + IconRef m_icon; Mutex m_eventMutex; Mutex m_eventConditionMutex; bool m_asyncWindow; diff --git a/include/Nazara/Utility/Window.inl b/include/Nazara/Utility/Window.inl index 0fce86ba6..c81c89b80 100644 --- a/include/Nazara/Utility/Window.inl +++ b/include/Nazara/Utility/Window.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -12,14 +12,6 @@ namespace Nz /*! * \class Nz::Window */ - inline Window::Window() : - m_impl(nullptr), - m_asyncWindow(false), - m_closeOnQuit(true), - m_eventPolling(false), - m_waitForEvent(false) - { - } inline Window::Window(VideoMode mode, const String& title, WindowStyleFlags style) : Window() @@ -75,6 +67,16 @@ namespace Nz } } + inline const CursorRef& Window::GetCursor() const + { + return m_cursor; + } + + inline CursorController& Nz::Window::GetCursorController() + { + return m_cursorController; + } + inline EventHandler& Nz::Window::GetEventHandler() { return m_eventHandler; @@ -104,6 +106,11 @@ namespace Nz return m_impl != nullptr; } + inline void Window::SetCursor(SystemCursor systemCursor) + { + SetCursor(Cursor::Get(systemCursor)); + } + inline void Window::HandleEvent(const WindowEvent& event) { if (m_eventPolling) diff --git a/include/Nazara/Utility/WindowHandle.hpp b/include/Nazara/Utility/WindowHandle.hpp index 9b5e34c83..f49a400e0 100644 --- a/include/Nazara/Utility/WindowHandle.hpp +++ b/include/Nazara/Utility/WindowHandle.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/plugins/Assimp/CustomStream.cpp b/plugins/Assimp/CustomStream.cpp index 6dbdd90b6..04e8cddce 100644 --- a/plugins/Assimp/CustomStream.cpp +++ b/plugins/Assimp/CustomStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Assimp Plugin" // For conditions of distribution and use, see copyright notice in Plugin.cpp diff --git a/plugins/Assimp/CustomStream.hpp b/plugins/Assimp/CustomStream.hpp index 9cb155e7c..55197d05c 100644 --- a/plugins/Assimp/CustomStream.hpp +++ b/plugins/Assimp/CustomStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Assimp Plugin" // For conditions of distribution and use, see copyright notice in Plugin.cpp diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index e65d460db..744434137 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -108,21 +108,21 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) if (parameters.optimizeIndexBuffers) postProcess |= aiProcess_ImproveCacheLocality; - float smoothingAngle = 80.f; - parameters.custom.GetFloatParameter("AssimpLoader_SmoothingAngle", &smoothingAngle); + double smoothingAngle = 80.f; + parameters.custom.GetDoubleParameter("AssimpLoader_SmoothingAngle", &smoothingAngle); - int triangleLimit = 1'000'000; + long long triangleLimit = 1'000'000; parameters.custom.GetIntegerParameter("AssimpLoader_TriangleLimit", &triangleLimit); - int vertexLimit = 1'000'000; + long long vertexLimit = 1'000'000; parameters.custom.GetIntegerParameter("AssimpLoader_VertexLimit", &vertexLimit); aiPropertyStore* properties = aiCreatePropertyStore(); - aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, smoothingAngle); + aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, float(smoothingAngle)); aiSetImportPropertyInteger(properties, AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4); aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SBP_REMOVE, ~aiPrimitiveType_TRIANGLE); //< We only want triangles - aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, triangleLimit); - aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, vertexLimit); + aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, int(triangleLimit)); + aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, int(vertexLimit)); aiSetImportPropertyInteger(properties, AI_CONFIG_PP_RVC_FLAGS, aiComponent_COLORS); const aiScene* scene = aiImportFileExWithProperties(userdata.originalFilePath, postProcess, &fileIO, properties); @@ -141,19 +141,19 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { - aiMesh* mesh = scene->mMeshes[i]; - if (mesh->HasBones()) // Inline functions can be safely called + aiMesh* currentMesh = scene->mMeshes[i]; + if (currentMesh->HasBones()) // Inline functions can be safely called { animatedMesh = true; - for (unsigned int j = 0; j < mesh->mNumBones; ++j) - joints.insert(mesh->mBones[j]->mName.C_Str()); + for (unsigned int j = 0; j < currentMesh->mNumBones; ++j) + joints.insert(currentMesh->mBones[j]->mName.C_Str()); } } } if (animatedMesh) { - mesh->CreateSkeletal(joints.size()); + mesh->CreateSkeletal(UInt32(joints.size())); Skeleton* skeleton = mesh->GetSkeleton(); @@ -171,7 +171,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) mesh->CreateStatic(); // aiMaterial index in scene => Material index and data in Mesh - std::unordered_map> materials; + std::unordered_map> materials; for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { @@ -276,7 +276,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) break; } - matData.SetParameter(wrapKey, static_cast(wrap)); + matData.SetParameter(wrapKey, static_cast(wrap)); } } }; @@ -300,7 +300,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue) == aiReturn_SUCCESS) matData.SetParameter(MaterialData::FaceCulling, !iValue); - matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(materials.size(), std::move(matData)))).first; + matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(UInt32(materials.size()), std::move(matData)))).first; } subMesh->SetMaterialIndex(matIt->first); @@ -308,7 +308,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) mesh->AddSubMesh(subMesh); } - mesh->SetMaterialCount(std::max(materials.size(), 1)); + mesh->SetMaterialCount(std::max(UInt32(materials.size()), 1)); for (const auto& pair : materials) mesh->SetMaterialData(pair.second.first, pair.second.second); } diff --git a/readme_fr.md b/readme_fr.md index 808788b0d..22215c42c 100644 --- a/readme_fr.md +++ b/readme_fr.md @@ -43,7 +43,7 @@ Vous pouvez lire des tutoriaux sur l'installation, la compilation et l'utilisati [Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) [Forum](https://forum.digitalpulsesoftware.net) -###Remerciements: +### Remerciements: - **RafBill** et **Raakz:** Recherche de bugs et/ou tests - **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur diff --git a/src/Nazara/Audio/Audio.cpp b/src/Nazara/Audio/Audio.cpp index 6eaa86c39..08ff28198 100644 --- a/src/Nazara/Audio/Audio.cpp +++ b/src/Nazara/Audio/Audio.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Debug/NewOverload.cpp b/src/Nazara/Audio/Debug/NewOverload.cpp index 359db9756..85431a7a0 100644 --- a/src/Nazara/Audio/Debug/NewOverload.cpp +++ b/src/Nazara/Audio/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 055e3b6a6..25c30e4ad 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Formats/sndfileLoader.hpp b/src/Nazara/Audio/Formats/sndfileLoader.hpp index 01576d5a3..724b5a5fe 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.hpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index b2b0e7e3b..cdfe4caac 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/OpenAL.cpp b/src/Nazara/Audio/OpenAL.cpp index 489855022..755a68a0b 100644 --- a/src/Nazara/Audio/OpenAL.cpp +++ b/src/Nazara/Audio/OpenAL.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 3e2e27faa..87e15ee2c 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index 4b2b0410e..2888710f1 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/SoundEmitter.cpp b/src/Nazara/Audio/SoundEmitter.cpp index 840c4f47d..4492771f4 100644 --- a/src/Nazara/Audio/SoundEmitter.cpp +++ b/src/Nazara/Audio/SoundEmitter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/SoundStream.cpp b/src/Nazara/Audio/SoundStream.cpp index 88bc0069b..eec87ccc1 100644 --- a/src/Nazara/Audio/SoundStream.cpp +++ b/src/Nazara/Audio/SoundStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Core/AbstractHash.cpp b/src/Nazara/Core/AbstractHash.cpp index 419ba74e9..ae2cb63b5 100644 --- a/src/Nazara/Core/AbstractHash.cpp +++ b/src/Nazara/Core/AbstractHash.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/AbstractLogger.cpp b/src/Nazara/Core/AbstractLogger.cpp index a1bf859a7..4ae945c0a 100644 --- a/src/Nazara/Core/AbstractLogger.cpp +++ b/src/Nazara/Core/AbstractLogger.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/AlgorithmCore.cpp b/src/Nazara/Core/AlgorithmCore.cpp index 1a9d8a171..6d6b09b80 100644 --- a/src/Nazara/Core/AlgorithmCore.cpp +++ b/src/Nazara/Core/AlgorithmCore.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 592170e40..4402af91d 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/ByteStream.cpp b/src/Nazara/Core/ByteStream.cpp index bc52f1782..489f90338 100644 --- a/src/Nazara/Core/ByteStream.cpp +++ b/src/Nazara/Core/ByteStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Clock.cpp b/src/Nazara/Core/Clock.cpp index 60482b18e..881d7c40e 100644 --- a/src/Nazara/Core/Clock.cpp +++ b/src/Nazara/Core/Clock.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Color.cpp b/src/Nazara/Core/Color.cpp index 35128a38d..d87ab5cc6 100644 --- a/src/Nazara/Core/Color.cpp +++ b/src/Nazara/Core/Color.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index 0730ea829..86ecb11ed 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 026e4a247..4a27bd482 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Debug/NewOverload.cpp b/src/Nazara/Core/Debug/NewOverload.cpp index 1638b4918..95b2fc888 100644 --- a/src/Nazara/Core/Debug/NewOverload.cpp +++ b/src/Nazara/Core/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Debug/NewRedefinition.cpp b/src/Nazara/Core/Debug/NewRedefinition.cpp index 73a467e5c..77aa93b00 100644 --- a/src/Nazara/Core/Debug/NewRedefinition.cpp +++ b/src/Nazara/Core/Debug/NewRedefinition.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index b48930419..1470a0f3d 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/DynLib.cpp b/src/Nazara/Core/DynLib.cpp index 515f437b4..10e5d4247 100644 --- a/src/Nazara/Core/DynLib.cpp +++ b/src/Nazara/Core/DynLib.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index 8de5e5747..1e50d87fb 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/ErrorFlags.cpp b/src/Nazara/Core/ErrorFlags.cpp index 003e37a23..01cc6fbcf 100644 --- a/src/Nazara/Core/ErrorFlags.cpp +++ b/src/Nazara/Core/ErrorFlags.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 35706fb70..9aa9374e0 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/FileLogger.cpp b/src/Nazara/Core/FileLogger.cpp index f08bd1b31..6dadfdcf1 100644 --- a/src/Nazara/Core/FileLogger.cpp +++ b/src/Nazara/Core/FileLogger.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index e43e07572..85270a562 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -312,9 +312,9 @@ namespace Nz while (!remainingRects.empty()) { // Stores the penalty score of the best rectangle placement - bigger=worse, smaller=better. - bool bestFlipped; - std::size_t bestFreeRect; - std::size_t bestRect; + bool bestFlipped = false; + std::size_t bestFreeRect = m_freeRectangles.size(); + std::size_t bestRect = std::numeric_limits::min(); int bestScore = std::numeric_limits::max(); for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index baef7c2f3..a4bec3194 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/CRC32.cpp b/src/Nazara/Core/Hash/CRC32.cpp index a7d0a87dc..db4a52634 100644 --- a/src/Nazara/Core/Hash/CRC32.cpp +++ b/src/Nazara/Core/Hash/CRC32.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/Fletcher16.cpp b/src/Nazara/Core/Hash/Fletcher16.cpp index 447a7ed3b..d1d563aca 100644 --- a/src/Nazara/Core/Hash/Fletcher16.cpp +++ b/src/Nazara/Core/Hash/Fletcher16.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/MD5.cpp b/src/Nazara/Core/Hash/MD5.cpp index 53082d4cc..b0f25d684 100644 --- a/src/Nazara/Core/Hash/MD5.cpp +++ b/src/Nazara/Core/Hash/MD5.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -101,7 +101,7 @@ namespace Nz { struct HashMD5_state { - UInt32 count[2]; /* message length in bits, lsw first */ + std::size_t count[2]; /* message length in bits, lsw first */ UInt32 abcd[4]; /* digest buffer */ UInt8 buf[64]; /* accumulate block */ }; @@ -280,9 +280,9 @@ namespace Nz void HashMD5::Append(const UInt8* data, std::size_t len) { const UInt8 *p = data; - int left = len; + std::size_t left = len; int offset = (m_state->count[0] >> 3) & 63; - UInt32 nbits = len << 3; + std::size_t nbits = len << 3; if (len <= 0) return; @@ -296,7 +296,7 @@ namespace Nz /* Process an initial partial block. */ if (offset) { - int copy = (offset + len > 64 ? 64 - offset : len); + std::size_t copy = (offset + len > 64 ? 64 - offset : len); std::memcpy(m_state->buf + offset, p, copy); if (offset + copy < 64) diff --git a/src/Nazara/Core/Hash/SHA/Internal.cpp b/src/Nazara/Core/Hash/SHA/Internal.cpp index ad5b1d30c..91d6d5e9c 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.cpp +++ b/src/Nazara/Core/Hash/SHA/Internal.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/SHA/Internal.hpp b/src/Nazara/Core/Hash/SHA/Internal.hpp index 711cec4bb..35171eeb9 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.hpp +++ b/src/Nazara/Core/Hash/SHA/Internal.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/SHA1.cpp b/src/Nazara/Core/Hash/SHA1.cpp index 6550d343d..6ba573a10 100644 --- a/src/Nazara/Core/Hash/SHA1.cpp +++ b/src/Nazara/Core/Hash/SHA1.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/SHA224.cpp b/src/Nazara/Core/Hash/SHA224.cpp index d071e9345..0cf5e8777 100644 --- a/src/Nazara/Core/Hash/SHA224.cpp +++ b/src/Nazara/Core/Hash/SHA224.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/SHA256.cpp b/src/Nazara/Core/Hash/SHA256.cpp index 9b5f56983..fec15b074 100644 --- a/src/Nazara/Core/Hash/SHA256.cpp +++ b/src/Nazara/Core/Hash/SHA256.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/SHA384.cpp b/src/Nazara/Core/Hash/SHA384.cpp index 3f647260e..7fdb85ea9 100644 --- a/src/Nazara/Core/Hash/SHA384.cpp +++ b/src/Nazara/Core/Hash/SHA384.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/SHA512.cpp b/src/Nazara/Core/Hash/SHA512.cpp index af56d937a..27812fdb7 100644 --- a/src/Nazara/Core/Hash/SHA512.cpp +++ b/src/Nazara/Core/Hash/SHA512.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Hash/Whirlpool.cpp b/src/Nazara/Core/Hash/Whirlpool.cpp index c3e7380ae..e01fb4f4f 100644 --- a/src/Nazara/Core/Hash/Whirlpool.cpp +++ b/src/Nazara/Core/Hash/Whirlpool.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -75,8 +75,8 @@ namespace Nz { struct HashWhirlpool_state { - int bufferBits; // current number of bits on the buffer */ - int bufferPos; // current (possibly incomplete) byte slot on the buffer */ + std::size_t bufferBits; // current number of bits on the buffer */ + std::size_t bufferPos; // current (possibly incomplete) byte slot on the buffer */ UInt8 bitLength[32]; // global number of hashed bits (256-bit counter) */ UInt8 buffer[64]; // buffer of data to hash */ UInt64 hash[8]; // the hashing state */ @@ -877,8 +877,8 @@ namespace Nz UInt32 b; UInt8* buffer = m_state->buffer; UInt8* bitLength = m_state->bitLength; - int bufferBits = m_state->bufferBits; - int bufferPos = m_state->bufferPos; + std::size_t bufferBits = m_state->bufferBits; + std::size_t bufferPos = m_state->bufferPos; // tally the length of the added data UInt64 value = len; @@ -968,8 +968,8 @@ namespace Nz UInt8 *buffer = m_state->buffer; UInt8 *bitLength = m_state->bitLength; - int bufferBits = m_state->bufferBits; - int bufferPos = m_state->bufferPos; + std::size_t bufferBits = m_state->bufferBits; + std::size_t bufferPos = m_state->bufferPos; UInt8 *digest = result; // append a '1'-bit diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index 1ff1ea373..b3dfed34a 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index 3a4883bec..aaf6bc520 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -413,9 +413,9 @@ namespace Nz while (ptr != &s_list) { if (ptr->file) - std::fprintf(log, "-0x%p -> %zu bytes allocated at %s:%u\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size, ptr->file, ptr->line); + std::fprintf(log, "-0x%s -> %zu bytes allocated at %s:%u\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size, ptr->file, ptr->line); else - std::fprintf(log, "-0x%p -> %zu bytes allocated at unknown position\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size); + std::fprintf(log, "-0x%s -> %zu bytes allocated at unknown position\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size); void* pointer = ptr; ptr = ptr->next; diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index a2fb7ff2b..fb5d8ca93 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index e501a031f..0d69b7a53 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index 68c94a8cf..953568ecc 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index bda37b4d4..89fdb4591 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -95,7 +95,7 @@ namespace Nz } case ParameterType_Color: - case ParameterType_Float: + case ParameterType_Double: case ParameterType_None: case ParameterType_Pointer: case ParameterType_Userdata: @@ -137,9 +137,9 @@ namespace Nz return true; case ParameterType_Boolean: + case ParameterType_Double: case ParameterType_Integer: case ParameterType_String: - case ParameterType_Float: case ParameterType_None: case ParameterType_Pointer: case ParameterType_Userdata: @@ -151,19 +151,19 @@ namespace Nz } /*! - * \brief Gets a parameter as a float - * \return true if the parameter could be represented as a float + * \brief Gets a parameter as a double + * \return true if the parameter could be represented as a double * * \param name Name of the parameter - * \param value Pointer to a float to hold the retrieved value + * \param value Pointer to a double to hold the retrieved value * * \remark value must be a valid pointer * \remark In case of failure, the variable pointed by value keep its value - * \remark If the parameter is not a float, a conversion will be performed, compatibles types are: - Integer: The integer value is converted to its float representation + * \remark If the parameter is not a double, a conversion will be performed, compatibles types are: + Integer: The integer value is converted to its double representation String: Conversion obeys the rule as described by String::ToDouble */ - bool ParameterList::GetFloatParameter(const String& name, float* value) const + bool ParameterList::GetDoubleParameter(const String& name, double* value) const { NazaraAssert(value, "Invalid pointer"); @@ -178,12 +178,12 @@ namespace Nz switch (it->second.type) { - case ParameterType_Float: - *value = it->second.value.floatVal; + case ParameterType_Double: + *value = it->second.value.doubleVal; return true; case ParameterType_Integer: - *value = static_cast(it->second.value.intVal); + *value = static_cast(it->second.value.intVal); return true; case ParameterType_String: @@ -191,7 +191,7 @@ namespace Nz double converted; if (it->second.value.stringVal.ToDouble(&converted)) { - *value = static_cast(converted); + *value = converted; return true; } @@ -206,7 +206,7 @@ namespace Nz break; } - NazaraError("Parameter value is not representable as a float"); + NazaraError("Parameter value is not representable as a double"); return false; } @@ -219,12 +219,12 @@ namespace Nz * * \remark value must be a valid pointer * \remark In case of failure, the variable pointed by value keep its value - * \remark If the parameter is not a float, a conversion will be performed, compatibles types are: + * \remark If the parameter is not an integer, a conversion will be performed, compatibles types are: Boolean: The boolean is represented as 1 if true and 0 if false - Float: The floating-point value is truncated and converted to a integer - String: Conversion obeys the rule as described by String::ToInteger but fails if the value could not be represented as a int + Double: The floating-point value is truncated and converted to a integer + String: Conversion obeys the rule as described by String::ToInteger */ - bool ParameterList::GetIntegerParameter(const String& name, int* value) const + bool ParameterList::GetIntegerParameter(const String& name, long long* value) const { NazaraAssert(value, "Invalid pointer"); @@ -243,8 +243,8 @@ namespace Nz *value = (it->second.value.boolVal) ? 1 : 0; return true; - case ParameterType_Float: - *value = static_cast(it->second.value.floatVal); + case ParameterType_Double: + *value = static_cast(it->second.value.doubleVal); return true; case ParameterType_Integer: @@ -256,11 +256,8 @@ namespace Nz long long converted; if (it->second.value.stringVal.ToInteger(&converted)) { - if (converted <= std::numeric_limits::max() && converted >= std::numeric_limits::min()) - { - *value = static_cast(converted); - return true; - } + *value = converted; + return true; } break; } @@ -335,7 +332,7 @@ namespace Nz case ParameterType_Boolean: case ParameterType_Color: - case ParameterType_Float: + case ParameterType_Double: case ParameterType_Integer: case ParameterType_None: case ParameterType_String: @@ -358,7 +355,7 @@ namespace Nz * \remark If the parameter is not a string, a conversion will be performed, all types are compatibles: Boolean: Conversion obeys the rules of String::Boolean Color: Conversion obeys the rules of Color::ToString - Float: Conversion obeys the rules of String::Number + Double: Conversion obeys the rules of String::Number Integer: Conversion obeys the rules of String::Number None: An empty string is returned Pointer: Conversion obeys the rules of String::Pointer @@ -387,8 +384,8 @@ namespace Nz *value = it->second.value.colorVal.ToString(); return true; - case ParameterType_Float: - *value = String::Number(it->second.value.floatVal); + case ParameterType_Double: + *value = String::Number(it->second.value.doubleVal); return true; case ParameterType_Integer: @@ -560,18 +557,18 @@ namespace Nz } /*! - * \brief Sets a float parameter named `name` + * \brief Sets a double parameter named `name` * * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value The float value + * \param value The double value */ - void ParameterList::SetParameter(const String& name, float value) + void ParameterList::SetParameter(const String& name, double value) { Parameter& parameter = CreateValue(name); - parameter.type = ParameterType_Float; - parameter.value.floatVal = value; + parameter.type = ParameterType_Double; + parameter.value.doubleVal = value; } /*! @@ -582,7 +579,7 @@ namespace Nz * \param name Name of the parameter * \param value The integer value */ - void ParameterList::SetParameter(const String& name, int value) + void ParameterList::SetParameter(const String& name, long long value) { Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Integer; @@ -627,8 +624,8 @@ namespace Nz case ParameterType_Color: ss << "Color(" << it->second.value.colorVal.ToString() << ")"; break; - case ParameterType_Float: - ss << "Float(" << it->second.value.floatVal << ")"; + case ParameterType_Double: + ss << "Double(" << it->second.value.doubleVal << ")"; break; case ParameterType_Integer: ss << "Integer(" << it->second.value.intVal << ")"; @@ -692,7 +689,7 @@ namespace Nz { case ParameterType_Boolean: case ParameterType_Color: - case ParameterType_Float: + case ParameterType_Double: case ParameterType_Integer: case ParameterType_Pointer: std::memcpy(¶meter, &it->second, sizeof(Parameter)); @@ -764,7 +761,7 @@ namespace Nz case ParameterType_Boolean: case ParameterType_Color: - case ParameterType_Float: + case ParameterType_Double: case ParameterType_Integer: case ParameterType_None: case ParameterType_Pointer: diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index b71af6677..2a7fa8eee 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 5603ed79b..75b2275cc 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace Nz @@ -72,11 +73,47 @@ namespace Nz if (mode & OpenMode_Truncate) flags |= O_TRUNC; - ///TODO: lock - //if ((mode & OpenMode_Lock) == 0) - // shareMode |= FILE_SHARE_WRITE; - m_fileDescriptor = open64(filePath.GetConstBuffer(), flags, permissions); + + static struct flock lock; + + auto initialize_flock = [](struct flock& fileLock) + { + fileLock.l_type = F_WRLCK; + fileLock.l_start = 0; + fileLock.l_whence = SEEK_SET; + fileLock.l_len = 0; + fileLock.l_pid = getpid(); + }; + + initialize_flock(lock); + + if (fcntl(m_fileDescriptor, F_GETLK, &lock) == -1) + { + Close(); + NazaraError("Unable to detect presence of lock on the file"); + return false; + } + + if (lock.l_type != F_UNLCK) + { + Close(); + NazaraError("A lock is present on the file"); + return false; + } + + if (mode & OpenMode_Lock) + { + initialize_flock(lock); + + if (fcntl(m_fileDescriptor, F_SETLK, &lock) == -1) + { + Close(); + NazaraError("Unable to place a lock on the file"); + return false; + } + } + return m_fileDescriptor != -1; } @@ -128,10 +165,7 @@ namespace Nz std::size_t FileImpl::Write(const void* buffer, std::size_t size) { - lockf64(m_fileDescriptor, F_LOCK, size); ssize_t written = write(m_fileDescriptor, buffer, size); - lockf64(m_fileDescriptor, F_ULOCK, size); - m_endOfFileUpdated = false; return written; diff --git a/src/Nazara/Core/Posix/ThreadImpl.cpp b/src/Nazara/Core/Posix/ThreadImpl.cpp index c16424328..aa0b87c5d 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.cpp +++ b/src/Nazara/Core/Posix/ThreadImpl.cpp @@ -5,8 +5,9 @@ #include #include #include +#include +#include #include -#include #include namespace Nz @@ -28,6 +29,43 @@ namespace Nz pthread_join(m_handle, nullptr); } + void ThreadImpl::SetName(const Nz::String& name) + { +#ifdef __GNUC__ + pthread_setname_np(m_handle, name.GetConstBuffer()); +#else + NazaraWarning("Setting thread name is not supported on this platform"); +#endif + } + + void ThreadImpl::SetCurrentName(const Nz::String& name) + { +#ifdef __GNUC__ + pthread_setname_np(pthread_self(), name.GetConstBuffer()); +#else + NazaraWarning("Setting current thread name is not supported on this platform"); +#endif + } + + void ThreadImpl::Sleep(UInt32 time) + { + if (time == 0) + sched_yield(); + else + { + struct timespec ts; + ts.tv_sec = time / 1000; + ts.tv_nsec = (time - ts.tv_sec * 1000) * 1'000'000; + + int r; + do + { + r = nanosleep(&ts, &ts); + } + while (r == -1 && errno == EINTR); + } + } + void* ThreadImpl::ThreadProc(void* userdata) { Functor* func = static_cast(userdata); @@ -36,40 +74,4 @@ namespace Nz return nullptr; } - - void ThreadImpl::Sleep(UInt32 time) - { - // code from SFML2 Unix SleepImpl.cpp source https://github.com/LaurentGomila/SFML/blob/master/src/SFML/System/Unix/SleepImpl.cpp - - // usleep is not reliable enough (it might block the - // whole process instead of just the current thread) - // so we must use pthread_cond_timedwait instead - - // this implementation is inspired from Qt - - // get the current time - timeval tv; - gettimeofday(&tv, nullptr); - - // construct the time limit (current time + time to wait) - timespec ti; - ti.tv_nsec = (tv.tv_usec + (time % 1000)) * 1000; - ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000); - ti.tv_nsec %= 1000000000; - - // create a mutex and thread condition - pthread_mutex_t mutex; - pthread_mutex_init(&mutex, nullptr); - pthread_cond_t condition; - pthread_cond_init(&condition, nullptr); - - // wait... - pthread_mutex_lock(&mutex); - pthread_cond_timedwait(&condition, &mutex, &ti); - pthread_mutex_unlock(&mutex); - - // destroy the mutex and condition - pthread_cond_destroy(&condition); - pthread_mutex_destroy(&mutex); - } } diff --git a/src/Nazara/Core/Posix/ThreadImpl.hpp b/src/Nazara/Core/Posix/ThreadImpl.hpp index 1ed6f3c8a..ba3d4ed84 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.hpp +++ b/src/Nazara/Core/Posix/ThreadImpl.hpp @@ -8,6 +8,12 @@ #define NAZARA_THREADIMPL_HPP #include +#include + +#if defined(__GNUC__) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + #include namespace Nz @@ -21,7 +27,9 @@ namespace Nz void Detach(); void Join(); + void SetName(const Nz::String& name); + static void SetCurrentName(const Nz::String& name); static void Sleep(UInt32 time); private: diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index a8d406b94..038ebe98e 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index 31e749515..9532e5d86 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 82ef768d1..efd8a4eb6 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Semaphore.cpp b/src/Nazara/Core/Semaphore.cpp index 1b2194095..e4a52b43f 100644 --- a/src/Nazara/Core/Semaphore.cpp +++ b/src/Nazara/Core/Semaphore.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/SerializationContext.cpp b/src/Nazara/Core/SerializationContext.cpp index 734b3b23d..e1665a416 100644 --- a/src/Nazara/Core/SerializationContext.cpp +++ b/src/Nazara/Core/SerializationContext.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/StdLogger.cpp b/src/Nazara/Core/StdLogger.cpp index c8dfc60bb..9fb14c140 100644 --- a/src/Nazara/Core/StdLogger.cpp +++ b/src/Nazara/Core/StdLogger.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index f82591fed..afc213814 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index ac01bf92c..98a8b882c 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -2115,7 +2115,7 @@ namespace Nz return ptr - m_sharedString->string.get(); } - catch (utf8::not_enough_room& e) + catch (utf8::not_enough_room& /*e*/) { // Returns npos } @@ -5079,7 +5079,7 @@ namespace Nz * \return The expected result * * \param first First string to use for comparison - * \parma second Second string to use for comparison + * \param second Second string to use for comparison */ int String::Compare(const String& first, const String& second) @@ -5093,6 +5093,27 @@ namespace Nz return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()); } + /*! + * \brief Build a string using a format and returns it + * \return Formatted string + * + * \param format String format + * \param args Format arguments + */ + String String::FormatVA(const char* format, va_list args) + { + // Copy va_list to use it twice + va_list args2; + va_copy(args2, args); + + std::size_t length = std::vsnprintf(nullptr, 0, format, args); + + auto str = std::make_shared(length); + std::vsnprintf(str->string.get(), length + 1, format, args2); + + return String(std::move(str)); + } + /*! * \brief Converts the number to string * \return String representation of the number diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index 0b27077e5..d39b3afb8 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index a29436407..fc14c5ea6 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index 0c4cd8008..d8b0ebd42 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -117,6 +117,25 @@ namespace Nz m_impl = nullptr; } + /*! + * \brief Changes the debugging name associated to a thread + * + * Changes the debugging name associated with a particular thread, and may helps with debugging tools. + * + * \param name The new name of the thread + * + * \remark Due to system limitations, thread name cannot exceed 15 characters (excluding null-terminator) + * + * \see SetCurrentThreadName + */ + void Thread::SetName(const String& name) + { + NazaraAssert(m_impl, "Invalid thread"); + NazaraAssert(name.GetSize() < 16, "Thread name is too long"); + + m_impl->SetName(name); + } + /*! * \brief Moves the other thread into this * \return A reference to this @@ -145,18 +164,35 @@ namespace Nz * \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 Changes the debugging name associated to the calling thread + * + * Changes the debugging name associated with the calling thread, and may helps with debugging tools. + * + * \param name The new name associated with this thread + * + * \remark Due to system limitations, thread name cannot exceed 15 characters (excluding null-terminator) + * + * \see SetName + */ + void Thread::SetCurrentThreadName(const String& name) + { + NazaraAssert(name.GetSize() < 16, "Thread name is too long"); + + ThreadImpl::SetCurrentName(name); + } + /*! * \brief Makes sleep this thread * * \param milliseconds The number of milliseconds to sleep */ - void Thread::Sleep(UInt32 milliseconds) { ThreadImpl::Sleep(milliseconds); diff --git a/src/Nazara/Core/Unicode.cpp b/src/Nazara/Core/Unicode.cpp index 0f6dd8452..cec6dbba8 100644 --- a/src/Nazara/Core/Unicode.cpp +++ b/src/Nazara/Core/Unicode.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Updatable.cpp b/src/Nazara/Core/Updatable.cpp index 3699b10a6..1ce56e3fd 100644 --- a/src/Nazara/Core/Updatable.cpp +++ b/src/Nazara/Core/Updatable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/ClockImpl.cpp b/src/Nazara/Core/Win32/ClockImpl.cpp index 311688d29..d78e7328c 100644 --- a/src/Nazara/Core/Win32/ClockImpl.cpp +++ b/src/Nazara/Core/Win32/ClockImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/ClockImpl.hpp b/src/Nazara/Core/Win32/ClockImpl.hpp index f1bcf8aaa..46411b68b 100644 --- a/src/Nazara/Core/Win32/ClockImpl.hpp +++ b/src/Nazara/Core/Win32/ClockImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/ConditionVariableImpl.cpp b/src/Nazara/Core/Win32/ConditionVariableImpl.cpp index a387a7638..7cd5416a8 100644 --- a/src/Nazara/Core/Win32/ConditionVariableImpl.cpp +++ b/src/Nazara/Core/Win32/ConditionVariableImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/ConditionVariableImpl.hpp b/src/Nazara/Core/Win32/ConditionVariableImpl.hpp index 469cf6099..36b559ff3 100644 --- a/src/Nazara/Core/Win32/ConditionVariableImpl.hpp +++ b/src/Nazara/Core/Win32/ConditionVariableImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/DirectoryImpl.cpp b/src/Nazara/Core/Win32/DirectoryImpl.cpp index 9901b9c10..824d81746 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.cpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/DirectoryImpl.hpp b/src/Nazara/Core/Win32/DirectoryImpl.hpp index 843587d52..141d4070c 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.hpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/DynLibImpl.cpp b/src/Nazara/Core/Win32/DynLibImpl.cpp index 0256e40fb..aa42fda18 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.cpp +++ b/src/Nazara/Core/Win32/DynLibImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/DynLibImpl.hpp b/src/Nazara/Core/Win32/DynLibImpl.hpp index aa2a3a9c1..e61969e84 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.hpp +++ b/src/Nazara/Core/Win32/DynLibImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index 1fb5a19eb..4e5d75c6c 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -191,9 +191,7 @@ namespace Nz LARGE_INTEGER cursorPos; cursorPos.QuadPart = GetCursorPos(); - LockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, static_cast(size), 0); WriteFile(m_handle, buffer, static_cast(size), &written, nullptr); - UnlockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, static_cast(size), 0); m_endOfFileUpdated = false; diff --git a/src/Nazara/Core/Win32/FileImpl.hpp b/src/Nazara/Core/Win32/FileImpl.hpp index dabfc266c..000835f6f 100644 --- a/src/Nazara/Core/Win32/FileImpl.hpp +++ b/src/Nazara/Core/Win32/FileImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp index 542c58d79..e1cdfaf50 100644 --- a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp +++ b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp index 3f923cfdd..f876cefb9 100644 --- a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp +++ b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/MutexImpl.cpp b/src/Nazara/Core/Win32/MutexImpl.cpp index 0dcce2aa3..7c4e18f34 100644 --- a/src/Nazara/Core/Win32/MutexImpl.cpp +++ b/src/Nazara/Core/Win32/MutexImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/MutexImpl.hpp b/src/Nazara/Core/Win32/MutexImpl.hpp index 8f5ad9010..ac9717846 100644 --- a/src/Nazara/Core/Win32/MutexImpl.hpp +++ b/src/Nazara/Core/Win32/MutexImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.cpp b/src/Nazara/Core/Win32/SemaphoreImpl.cpp index 31c329f2e..19bc17c74 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.hpp b/src/Nazara/Core/Win32/SemaphoreImpl.hpp index ac60cab1b..a78b2328f 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.hpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index ef83e4b28..3aba937e4 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp index aabd58b86..59dc79c73 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/ThreadImpl.cpp b/src/Nazara/Core/Win32/ThreadImpl.cpp index 2d62b860d..cae997874 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.cpp +++ b/src/Nazara/Core/Win32/ThreadImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -6,15 +6,32 @@ #include #include #include +#include #include namespace Nz { + namespace + { +#pragma pack(push,8) + struct THREADNAME_INFO + { + DWORD dwType; + LPCSTR szName; + DWORD dwThreadID; + DWORD dwFlags; + }; +#pragma pack(pop) + } + ThreadImpl::ThreadImpl(Functor* functor) { - m_handle = reinterpret_cast(_beginthreadex(nullptr, 0, &ThreadImpl::ThreadProc, functor, 0, nullptr)); + unsigned int threadId; + m_handle = reinterpret_cast(_beginthreadex(nullptr, 0, &ThreadImpl::ThreadProc, functor, 0, &threadId)); if (!m_handle) NazaraInternalError("Failed to create thread: " + Error::GetLastSystemError()); + + m_threadId = threadId; } void ThreadImpl::Detach() @@ -29,6 +46,44 @@ namespace Nz CloseHandle(m_handle); } + void ThreadImpl::SetName(const Nz::String& name) + { + SetThreadName(m_threadId, name.GetConstBuffer()); + } + + void ThreadImpl::SetCurrentName(const Nz::String& name) + { + SetThreadName(::GetCurrentThreadId(), name.GetConstBuffer()); + } + + void ThreadImpl::Sleep(UInt32 time) + { + ::Sleep(time); + } + + void ThreadImpl::SetThreadName(DWORD threadId, const char* threadName) + { + // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + constexpr DWORD MS_VC_EXCEPTION = 0x406D1388; + + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = threadId; + info.dwFlags = 0; + +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try + { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast(&info)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } +#pragma warning(pop) + } + unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata) { Functor* func = static_cast(userdata); @@ -42,9 +97,4 @@ namespace Nz return 0; } - - void ThreadImpl::Sleep(UInt32 time) - { - ::Sleep(time); - } } diff --git a/src/Nazara/Core/Win32/ThreadImpl.hpp b/src/Nazara/Core/Win32/ThreadImpl.hpp index d036c124c..8070f7a22 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.hpp +++ b/src/Nazara/Core/Win32/ThreadImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -10,6 +10,7 @@ #define NAZARA_THREADIMPL_HPP #include +#include #include namespace Nz @@ -23,12 +24,16 @@ namespace Nz void Detach(); void Join(); + void SetName(const Nz::String& name); + static void SetCurrentName(const Nz::String& name); static void Sleep(UInt32 time); private: + static void SetThreadName(DWORD threadId, const char* threadName); static unsigned int __stdcall ThreadProc(void* userdata); + DWORD m_threadId; HANDLE m_handle; }; } diff --git a/src/Nazara/Core/Win32/Time.cpp b/src/Nazara/Core/Win32/Time.cpp index 9ed58bc46..2fab92eb3 100644 --- a/src/Nazara/Core/Win32/Time.cpp +++ b/src/Nazara/Core/Win32/Time.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Core/Win32/Time.hpp b/src/Nazara/Core/Win32/Time.hpp index a0ba7da36..9ad8a7aa6 100644 --- a/src/Nazara/Core/Win32/Time.hpp +++ b/src/Nazara/Core/Win32/Time.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Graphics/AbstractBackground.cpp b/src/Nazara/Graphics/AbstractBackground.cpp index 28d0f0d4f..5d1f23a6d 100644 --- a/src/Nazara/Graphics/AbstractBackground.cpp +++ b/src/Nazara/Graphics/AbstractBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/AbstractRenderQueue.cpp b/src/Nazara/Graphics/AbstractRenderQueue.cpp index 1346e37ff..c623b218f 100644 --- a/src/Nazara/Graphics/AbstractRenderQueue.cpp +++ b/src/Nazara/Graphics/AbstractRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp index 9872178cf..8a33b7b46 100644 --- a/src/Nazara/Graphics/AbstractRenderTechnique.cpp +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/AbstractViewer.cpp b/src/Nazara/Graphics/AbstractViewer.cpp index bd8752bc7..e83737baa 100644 --- a/src/Nazara/Graphics/AbstractViewer.cpp +++ b/src/Nazara/Graphics/AbstractViewer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index 4aed923ae..c4382eefb 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ColorBackground.cpp b/src/Nazara/Graphics/ColorBackground.cpp index dcacb1a46..52653a8e7 100644 --- a/src/Nazara/Graphics/ColorBackground.cpp +++ b/src/Nazara/Graphics/ColorBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Debug/NewOverload.cpp b/src/Nazara/Graphics/Debug/NewOverload.cpp index 6c5b5c8f0..b79e8408e 100644 --- a/src/Nazara/Graphics/Debug/NewOverload.cpp +++ b/src/Nazara/Graphics/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index 643024ead..e51543641 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredDOFPass.cpp b/src/Nazara/Graphics/DeferredDOFPass.cpp index b39085400..9760ff300 100644 --- a/src/Nazara/Graphics/DeferredDOFPass.cpp +++ b/src/Nazara/Graphics/DeferredDOFPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredFXAAPass.cpp b/src/Nazara/Graphics/DeferredFXAAPass.cpp index d4ba72ddf..fa2d80d46 100644 --- a/src/Nazara/Graphics/DeferredFXAAPass.cpp +++ b/src/Nazara/Graphics/DeferredFXAAPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredFinalPass.cpp b/src/Nazara/Graphics/DeferredFinalPass.cpp index c4ab348eb..228e9d035 100644 --- a/src/Nazara/Graphics/DeferredFinalPass.cpp +++ b/src/Nazara/Graphics/DeferredFinalPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index f47a4ea56..c6fbfddf9 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredForwardPass.cpp b/src/Nazara/Graphics/DeferredForwardPass.cpp index ed7ad45d1..55780708f 100644 --- a/src/Nazara/Graphics/DeferredForwardPass.cpp +++ b/src/Nazara/Graphics/DeferredForwardPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index c6c6c59ed..6d5883c48 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index 8f83f9a6b..2eff9abc9 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredRenderPass.cpp b/src/Nazara/Graphics/DeferredRenderPass.cpp index 280f6658c..c4c265b58 100644 --- a/src/Nazara/Graphics/DeferredRenderPass.cpp +++ b/src/Nazara/Graphics/DeferredRenderPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 6aecb8a5a..a0455fe11 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -191,8 +191,8 @@ namespace Nz void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { - if (material->IsBlendingEnabled()) - // One transparent material ? I don't like it, go see if I'm in the forward queue + if (material->IsBlendingEnabled() || material->IsDepthSortingEnabled()) //< Fixme: Deferred Shading should be able to handle depth sorting + // Deferred Shading cannot handle blended objects, put them in the forward list m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix); else { @@ -254,7 +254,7 @@ namespace Nz * \param overlay Texture of the sprites */ - void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay) { m_forwardQueue->AddSprites(renderOrder, material, vertices, spriteCount, overlay); } diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index 45c8bf7c3..01a0d1fa8 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index fbc24bb19..a2acdf4bb 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -351,7 +351,7 @@ namespace Nz * \remark Produces a NazaraAssert if material is invalid */ - void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay) { NazaraAssert(material, "Invalid material"); NazaraUnused(renderOrder); diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 542b180a7..4acbbc56d 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -68,7 +68,7 @@ namespace Nz * \param sceneData Data of the scene */ - void DepthRenderTechnique::Clear(const SceneData& sceneData) const + void DepthRenderTechnique::Clear(const SceneData& /*sceneData*/) const { Renderer::Enable(RendererParameter_DepthBuffer, true); Renderer::Enable(RendererParameter_DepthWrite, true); @@ -95,7 +95,7 @@ namespace Nz if (!layer.opaqueModels.empty()) DrawOpaqueModels(sceneData, layer); - if (!layer.basicSprites.empty()) + if (!layer.opaqueSprites.empty()) DrawBasicSprites(sceneData, layer); if (!layer.billboards.empty()) @@ -212,8 +212,6 @@ namespace Nz void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -221,7 +219,7 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); Renderer::SetVertexBuffer(&m_spriteBuffer); - for (auto& pipelinePair : layer.basicSprites) + for (auto& pipelinePair : layer.opaqueSprites) { const MaterialPipeline* pipeline = pipelinePair.first; auto& pipelineEntry = pipelinePair.second; @@ -240,8 +238,6 @@ namespace Nz // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } @@ -253,13 +249,12 @@ namespace Nz if (matEntry.enabled) { - UInt8 overlayUnit; - material->Apply(pipelineInstance, 0, &overlayUnit); - overlayUnit++; + unsigned int overlayTextureUnit = Material::GetTextureUnit(TextureMap_Overlay); + material->Apply(pipelineInstance); - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + shader->SendInteger(shaderUniforms->textureOverlay, overlayTextureUnit); - Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + Renderer::SetTextureSampler(overlayTextureUnit, material->GetDiffuseSampler()); auto& overlayMap = matEntry.overlayMap; for (auto& overlayIt : overlayMap) @@ -270,7 +265,7 @@ namespace Nz std::size_t spriteChainCount = spriteChainVector.size(); if (spriteChainCount > 0) { - Renderer::SetTexture(overlayUnit, (overlay) ? overlay : &m_whiteTexture); + Renderer::SetTexture(overlayTextureUnit, (overlay) ? overlay : &m_whiteTexture); std::size_t spriteChain = 0; // Which chain of sprites are we treating std::size_t spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain @@ -330,8 +325,6 @@ namespace Nz void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -361,8 +354,6 @@ namespace Nz // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } @@ -423,8 +414,6 @@ namespace Nz // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } @@ -501,8 +490,6 @@ namespace Nz void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -526,8 +513,6 @@ namespace Nz // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } @@ -539,8 +524,7 @@ namespace Nz if (matEntry.enabled) { - UInt8 freeTextureUnit; - material->Apply(pipelineInstance, 0, &freeTextureUnit); + material->Apply(pipelineInstance); ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; @@ -641,7 +625,7 @@ namespace Nz uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &DepthRenderTechnique::OnShaderInvalidated); uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &DepthRenderTechnique::OnShaderInvalidated); - uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; diff --git a/src/Nazara/Graphics/Drawable.cpp b/src/Nazara/Graphics/Drawable.cpp index 7db121225..79df17ef1 100644 --- a/src/Nazara/Graphics/Drawable.cpp +++ b/src/Nazara/Graphics/Drawable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index 38f836e90..ad5d58736 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Formats/MeshLoader.hpp b/src/Nazara/Graphics/Formats/MeshLoader.hpp index db2a08bac..215e19c44 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.hpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index 7530726fb..d3667a945 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Formats/TextureLoader.hpp b/src/Nazara/Graphics/Formats/TextureLoader.hpp index 7d071c050..f068aeb5d 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.hpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 6c6915214..ba8c68358 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -376,23 +376,23 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - if (material->IsBlendingEnabled()) + if (material->IsDepthSortingEnabled()) { Layer& currentLayer = GetLayer(renderOrder); - auto& transparentModels = currentLayer.transparentModels; - auto& transparentModelData = currentLayer.transparentModelData; + auto& transparentMeshes = currentLayer.depthSortedMeshes; + auto& transparentData = currentLayer.depthSortedMeshData; - // The material is transparent, we must draw this mesh using another way (after the rendering of opages objects while sorting them) - std::size_t index = transparentModelData.size(); - transparentModelData.resize(index+1); + // The material is marked for depth sorting, we must draw this mesh using another way (after the rendering of opaques objects while sorting them) + std::size_t index = transparentData.size(); + transparentData.resize(index+1); - TransparentModelData& data = transparentModelData.back(); + UnbatchedModelData& data = transparentData.back(); data.material = material; data.meshData = meshData; - data.squaredBoundingSphere = Spheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); + data.obbSphere = Spheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); data.transformMatrix = transformMatrix; - transparentModels.push_back(index); + transparentMeshes.push_back(index); } else { @@ -457,53 +457,74 @@ namespace Nz * * \remark Produces a NazaraAssert if material is invalid */ - void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, std::size_t spriteCount, const Texture* overlay) { NazaraAssert(material, "Invalid material"); Layer& currentLayer = GetLayer(renderOrder); - SpritePipelineBatches& basicSprites = currentLayer.basicSprites; - const MaterialPipeline* materialPipeline = material->GetPipeline(); - - auto pipelineIt = basicSprites.find(materialPipeline); - if (pipelineIt == basicSprites.end()) + if (material->IsDepthSortingEnabled()) { - BatchedSpritePipelineEntry materialEntry; - pipelineIt = basicSprites.insert(SpritePipelineBatches::value_type(materialPipeline, std::move(materialEntry))).first; + auto& transparentSprites = currentLayer.depthSortedSprites; + auto& transparentData = currentLayer.depthSortedSpriteData; + + // The material is marked for depth sorting, we must draw this mesh using another way (after the rendering of opaques objects while sorting them) + std::size_t index = transparentData.size(); + transparentData.resize(index + 1); + + UnbatchedSpriteData& data = transparentData.back(); + data.material = material; + data.overlay = overlay; + data.spriteCount = spriteCount; + data.vertices = vertices; + + transparentSprites.push_back(index); } - - BatchedSpritePipelineEntry& pipelineEntry = pipelineIt->second; - pipelineEntry.enabled = true; - - SpriteMaterialBatches& materialMap = pipelineEntry.materialMap; - - auto matIt = materialMap.find(material); - if (matIt == materialMap.end()) + else { - BatchedBasicSpriteEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + SpritePipelineBatches& sprites = currentLayer.opaqueSprites; - matIt = materialMap.insert(SpriteMaterialBatches::value_type(material, std::move(entry))).first; + const MaterialPipeline* materialPipeline = material->GetPipeline(); + + auto pipelineIt = sprites.find(materialPipeline); + if (pipelineIt == sprites.end()) + { + BatchedSpritePipelineEntry materialEntry; + pipelineIt = sprites.insert(SpritePipelineBatches::value_type(materialPipeline, std::move(materialEntry))).first; + } + + BatchedSpritePipelineEntry& pipelineEntry = pipelineIt->second; + pipelineEntry.enabled = true; + + SpriteMaterialBatches& materialMap = pipelineEntry.materialMap; + + auto matIt = materialMap.find(material); + if (matIt == materialMap.end()) + { + BatchedBasicSpriteEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + matIt = materialMap.insert(SpriteMaterialBatches::value_type(material, std::move(entry))).first; + } + + BatchedBasicSpriteEntry& entry = matIt->second; + entry.enabled = true; + + auto& overlayMap = entry.overlayMap; + + auto overlayIt = overlayMap.find(overlay); + if (overlayIt == overlayMap.end()) + { + BatchedSpriteEntry overlayEntry; + if (overlay) + overlayEntry.textureReleaseSlot.Connect(overlay->OnTextureRelease, this, &ForwardRenderQueue::OnTextureInvalidation); + + overlayIt = overlayMap.insert(std::make_pair(overlay, std::move(overlayEntry))).first; + } + + auto& spriteVector = overlayIt->second.spriteChains; + spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } - - BatchedBasicSpriteEntry& entry = matIt->second; - entry.enabled = true; - - auto& overlayMap = entry.overlayMap; - - auto overlayIt = overlayMap.find(overlay); - if (overlayIt == overlayMap.end()) - { - BatchedSpriteEntry overlayEntry; - if (overlay) - overlayEntry.textureReleaseSlot.Connect(overlay->OnTextureRelease, this, &ForwardRenderQueue::OnTextureInvalidation); - - overlayIt = overlayMap.insert(std::make_pair(overlay, std::move(overlayEntry))).first; - } - - auto& spriteVector = overlayIt->second.spriteChains; - spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } /*! @@ -545,7 +566,7 @@ namespace Nz pipelineEntry.enabled = false; } - for (auto& pipelinePair : layer.basicSprites) + for (auto& pipelinePair : layer.opaqueSprites) { auto& pipelineEntry = pipelinePair.second; @@ -596,9 +617,11 @@ namespace Nz } } + layer.depthSortedMeshes.clear(); + layer.depthSortedMeshData.clear(); + layer.depthSortedSpriteData.clear(); + layer.depthSortedSprites.clear(); layer.otherDrawables.clear(); - layer.transparentModels.clear(); - layer.transparentModelData.clear(); ++it; } } @@ -613,44 +636,10 @@ namespace Nz void ForwardRenderQueue::Sort(const AbstractViewer* viewer) { - Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near); - Vector3f viewerPos = viewer->GetEyePosition(); - Vector3f viewerNormal = viewer->GetForward(); - - for (auto& pair : layers) - { - Layer& layer = pair.second; - - std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (std::size_t index1, std::size_t index2) - { - const Spheref& sphere1 = layer.transparentModelData[index1].squaredBoundingSphere; - const Spheref& sphere2 = layer.transparentModelData[index2].squaredBoundingSphere; - - Vector3f position1 = sphere1.GetNegativeVertex(viewerNormal); - Vector3f position2 = sphere2.GetNegativeVertex(viewerNormal); - - return nearPlane.Distance(position1) > nearPlane.Distance(position2); - }); - - for (auto& pipelinePair : layer.billboards) - { - for (auto& matPair : pipelinePair.second.materialMap) - { - const Material* mat = matPair.first; - - if (mat->IsDepthSortingEnabled()) - { - BatchedBillboardEntry& entry = matPair.second; - auto& billboardVector = entry.billboards; - - std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos] (const BillboardData& data1, const BillboardData& data2) - { - return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); - }); - } - } - } - } + if (viewer->GetProjectionType() == ProjectionType_Orthogonal) + SortForOrthographic(viewer); + else + SortForPerspective(viewer); } /*! @@ -715,12 +704,91 @@ namespace Nz return layer; } + void ForwardRenderQueue::SortBillboards(Layer& layer, const Planef& nearPlane) + { + for (auto& pipelinePair : layer.billboards) + { + for (auto& matPair : pipelinePair.second.materialMap) + { + const Material* mat = matPair.first; + + if (mat->IsDepthSortingEnabled()) + { + BatchedBillboardEntry& entry = matPair.second; + auto& billboardVector = entry.billboards; + + std::sort(billboardVector.begin(), billboardVector.end(), [&nearPlane] (const BillboardData& data1, const BillboardData& data2) + { + return nearPlane.Distance(data1.center) > nearPlane.Distance(data2.center); + }); + } + } + } + } + + void ForwardRenderQueue::SortForOrthographic(const AbstractViewer * viewer) + { + Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near); + Vector3f viewerPos = viewer->GetEyePosition(); + + for (auto& pair : layers) + { + Layer& layer = pair.second; + + std::sort(layer.depthSortedMeshes.begin(), layer.depthSortedMeshes.end(), [&layer, &nearPlane] (std::size_t index1, std::size_t index2) + { + const Spheref& sphere1 = layer.depthSortedMeshData[index1].obbSphere; + const Spheref& sphere2 = layer.depthSortedMeshData[index2].obbSphere; + + return nearPlane.Distance(sphere1.GetPosition()) < nearPlane.Distance(sphere2.GetPosition()); + }); + + std::sort(layer.depthSortedSprites.begin(), layer.depthSortedSprites.end(), [&layer, &nearPlane] (std::size_t index1, std::size_t index2) + { + const Vector3f& pos1 = layer.depthSortedSpriteData[index1].vertices[0].position; + const Vector3f& pos2 = layer.depthSortedSpriteData[index2].vertices[0].position; + + return nearPlane.Distance(pos1) < nearPlane.Distance(pos2); + }); + + SortBillboards(layer, nearPlane); + } + } + + void ForwardRenderQueue::SortForPerspective(const AbstractViewer* viewer) + { + Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near); + Vector3f viewerPos = viewer->GetEyePosition(); + + for (auto& pair : layers) + { + Layer& layer = pair.second; + + std::sort(layer.depthSortedMeshes.begin(), layer.depthSortedMeshes.end(), [&layer, &viewerPos] (std::size_t index1, std::size_t index2) + { + const Spheref& sphere1 = layer.depthSortedMeshData[index1].obbSphere; + const Spheref& sphere2 = layer.depthSortedMeshData[index2].obbSphere; + + return viewerPos.SquaredDistance(sphere1.GetPosition()) > viewerPos.SquaredDistance(sphere2.GetPosition()); + }); + + std::sort(layer.depthSortedSprites.begin(), layer.depthSortedSprites.end(), [&layer, &viewerPos] (std::size_t index1, std::size_t index2) + { + const Vector3f& pos1 = layer.depthSortedSpriteData[index1].vertices[0].position; + const Vector3f& pos2 = layer.depthSortedSpriteData[index2].vertices[0].position; + + return viewerPos.SquaredDistance(pos1) > viewerPos.SquaredDistance(pos2); + }); + + SortBillboards(layer, nearPlane); + } + } + /*! * \brief Handle the invalidation of an index buffer * * \param indexBuffer Index buffer being invalidated */ - void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { for (auto& pair : layers) @@ -757,7 +825,7 @@ namespace Nz { Layer& layer = pair.second; - for (auto& pipelineEntry : layer.basicSprites) + for (auto& pipelineEntry : layer.opaqueSprites) pipelineEntry.second.materialMap.erase(material); for (auto& pipelineEntry : layer.billboards) @@ -779,7 +847,7 @@ namespace Nz for (auto& pair : layers) { Layer& layer = pair.second; - for (auto& pipelineEntry : layer.basicSprites) + for (auto& pipelineEntry : layer.opaqueSprites) { for (auto& materialEntry : pipelineEntry.second.materialMap) materialEntry.second.overlayMap.erase(texture); diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 22961b157..1d202c837 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -33,8 +33,8 @@ namespace Nz Vector2f uv; }; - std::size_t s_maxQuads = std::numeric_limits::max() / 6; - std::size_t s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB + UInt32 s_maxQuads = std::numeric_limits::max() / 6; + UInt32 s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB } /*! @@ -101,12 +101,15 @@ namespace Nz if (!layer.opaqueModels.empty()) DrawOpaqueModels(sceneData, layer); - if (!layer.transparentModels.empty()) + if (!layer.depthSortedMeshes.empty()) DrawTransparentModels(sceneData, layer); - if (!layer.basicSprites.empty()) + if (!layer.opaqueSprites.empty()) DrawBasicSprites(sceneData, layer); + if (!layer.depthSortedSprites.empty()) + DrawOrderedSprites(sceneData, layer); + if (!layer.billboards.empty()) DrawBillboards(sceneData, layer); @@ -301,7 +304,10 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); Renderer::SetVertexBuffer(&m_spriteBuffer); - for (auto& pipelinePair : layer.basicSprites) + const unsigned int overlayTextureUnit = Material::GetTextureUnit(TextureMap_Overlay); + const std::size_t maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount() / 4); + + for (auto& pipelinePair : layer.opaqueSprites) { const MaterialPipeline* pipeline = pipelinePair.first; auto& pipelineEntry = pipelinePair.second; @@ -318,11 +324,14 @@ namespace Nz // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Ambiant color of the scene + // Ambient color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + // Overlay texture unit + shader->SendInteger(shaderUniforms->textureOverlay, overlayTextureUnit); + lastShader = shader; } @@ -333,13 +342,9 @@ namespace Nz if (matEntry.enabled) { - UInt8 overlayUnit; - material->Apply(pipelineInstance, 0, &overlayUnit); - overlayUnit++; + material->Apply(pipelineInstance); - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - - Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + Renderer::SetTextureSampler(overlayTextureUnit, material->GetDiffuseSampler()); auto& overlayMap = matEntry.overlayMap; for (auto& overlayIt : overlayMap) @@ -350,7 +355,7 @@ namespace Nz std::size_t spriteChainCount = spriteChainVector.size(); if (spriteChainCount > 0) { - Renderer::SetTexture(overlayUnit, (overlay) ? overlay : &m_whiteTexture); + Renderer::SetTexture(overlayTextureUnit, (overlay) ? overlay : &m_whiteTexture); std::size_t spriteChain = 0; // Which chain of sprites are we treating std::size_t spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain @@ -362,7 +367,6 @@ namespace Nz VertexStruct_XYZ_Color_UV* vertices = static_cast(vertexMapper.GetPointer()); std::size_t spriteCount = 0; - std::size_t maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount() / 4); do { @@ -616,8 +620,7 @@ namespace Nz if (matEntry.enabled) { - UInt8 freeTextureUnit; - material->Apply(pipelineInstance, 0, &freeTextureUnit); + material->Apply(pipelineInstance); ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; @@ -688,8 +691,8 @@ namespace Nz } // Sends the uniforms - for (std::size_t i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i); + for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, lightIndex++, shaderUniforms->lightOffset * i); } const Matrix4f* instanceMatrices = &instances[0]; @@ -747,8 +750,8 @@ namespace Nz } // Sends the light uniforms to the shader - for (std::size_t i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); + for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, lightIndex++, shaderUniforms->lightOffset*i); // And we draw drawFunc(meshData.primitiveMode, 0, indexCount); @@ -778,6 +781,142 @@ namespace Nz } } + void ForwardRenderTechnique::DrawOrderedSprites(const SceneData & sceneData, ForwardRenderQueue::Layer & layer) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); + Renderer::SetVertexBuffer(&m_spriteBuffer); + + const Material* lastMaterial = nullptr; + const MaterialPipeline* lastPipeline = nullptr; + const Shader* lastShader = nullptr; + const Texture* lastOverlay = nullptr; + const MaterialPipeline::Instance* pipelineInstance = nullptr; + + const unsigned int overlayTextureUnit = Material::GetTextureUnit(TextureMap_Overlay); + + bool updateVertexBuffer = true; + const std::size_t maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount() / 4); + + std::size_t alreadyDrawnCount = 0; + std::size_t spriteIndex = 0; + std::size_t spriteChainOffset = 0; + auto splitChainIt = layer.depthSortedSprites.end(); + + for (auto it = layer.depthSortedSprites.begin(); it != layer.depthSortedSprites.end();) + { + if (updateVertexBuffer) + { + // We open the buffer in writing mode + BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); + VertexStruct_XYZ_Color_UV* vertices = static_cast(vertexMapper.GetPointer()); + + std::size_t availableSpriteSpace = maxSpriteCount; + bool split = false; + for (auto it2 = it; it2 != layer.depthSortedSprites.end(); ++it2) + { + const ForwardRenderQueue::UnbatchedSpriteData& spriteData = layer.depthSortedSpriteData[*it2]; + + std::size_t count = std::min(availableSpriteSpace, spriteData.spriteCount - spriteChainOffset); + + std::memcpy(vertices, spriteData.vertices + spriteChainOffset * 4, 4 * count * sizeof(VertexStruct_XYZ_Color_UV)); + vertices += count * 4; + + availableSpriteSpace -= count; + + // Have we treated the entire chain ? + if (count != spriteData.spriteCount) + { + // Oops, not enough space to store current chain + spriteChainOffset += count; + splitChainIt = it2; + split = true; + break; + } + + // Switch to next sprite chain, if any + spriteChainOffset = 0; + } + + spriteIndex = 0; + updateVertexBuffer = false; + + if (!split) + splitChainIt = layer.depthSortedSprites.end(); + } + + std::size_t index = *it; + + const ForwardRenderQueue::UnbatchedSpriteData& spriteData = layer.depthSortedSpriteData[index]; + + const Material* material = spriteData.material; + if (material != lastMaterial) + { + const MaterialPipeline* pipeline = material->GetPipeline(); + if (pipeline != lastPipeline) + { + pipelineInstance = &pipeline->Apply(ShaderFlags_TextureOverlay | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance->uberInstance->GetShader(); + + // Uniforms are conserved in our program, there's no point to send them back until they change + if (shader != lastShader) + { + // Index of uniforms in the shader + const ShaderUniforms* shaderUniforms = GetShaderUniforms(shader); + + // Ambient color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position of the camera + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + // Overlay texture unit + shader->SendInteger(shaderUniforms->textureOverlay, overlayTextureUnit); + + lastShader = shader; + } + + lastPipeline = pipeline; + } + + material->Apply(*pipelineInstance); + + Renderer::SetTextureSampler(overlayTextureUnit, material->GetDiffuseSampler()); + + lastMaterial = material; + } + + const Texture* overlay = (spriteData.overlay) ? spriteData.overlay : &m_whiteTexture; + if (overlay != lastOverlay) + { + Renderer::SetTexture(overlayTextureUnit, overlay); + lastOverlay = overlay; + } + + std::size_t spriteCount; + if (it != splitChainIt) + { + spriteCount = spriteData.spriteCount - alreadyDrawnCount; + alreadyDrawnCount = 0; + + ++it; + } + else + { + spriteCount = spriteChainOffset; + + alreadyDrawnCount = spriteCount; + updateVertexBuffer = true; + + // Restart at current iterator next time + } + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, spriteIndex * 6, spriteCount * 6); + spriteIndex += spriteCount; + } + } + /*! * \brief Draws transparent models * @@ -797,9 +936,9 @@ namespace Nz const ShaderUniforms* shaderUniforms = nullptr; unsigned int lightCount = 0; - for (unsigned int index : layer.transparentModels) + for (std::size_t index : layer.depthSortedMeshes) { - const ForwardRenderQueue::TransparentModelData& modelData = layer.transparentModelData[index]; + const ForwardRenderQueue::UnbatchedModelData& modelData = layer.depthSortedMeshData[index]; // Material const Material* material = modelData.material; @@ -812,8 +951,7 @@ namespace Nz } // We begin to apply the material - UInt8 freeTextureUnit; - material->Apply(*pipelineInstance, 0, &freeTextureUnit); + material->Apply(*pipelineInstance); // Uniforms are conserved in our program, there's no point to send them back until they change const Shader* shader = pipelineInstance->uberInstance->GetShader(); @@ -833,7 +971,7 @@ namespace Nz lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); for (std::size_t i = 0; i < lightCount; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i, freeTextureUnit++); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, i, shaderUniforms->lightOffset * i); } lastShader = shader; @@ -867,12 +1005,12 @@ namespace Nz if (shaderUniforms->hasLightUniforms && lightCount < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS) { // Compute the closest lights - Vector3f position = matrix.GetTranslation() + modelData.squaredBoundingSphere.GetPosition(); - float radius = modelData.squaredBoundingSphere.radius; + Vector3f position = matrix.GetTranslation() + modelData.obbSphere.GetPosition(); + float radius = modelData.obbSphere.radius; ChooseLights(Spheref(position, radius), false); for (std::size_t i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i, freeTextureUnit++); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, i, shaderUniforms->lightOffset*i); } Renderer::SetMatrix(MatrixType_World, matrix); @@ -915,9 +1053,7 @@ namespace Nz uniforms.lightUniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); - uniforms.lightUniforms.locations.pointLightShadowMap = shader->GetUniformLocation("PointLightShadowMap[0]"); uniforms.lightUniforms.locations.shadowMapping = shader->GetUniformLocation("Lights[0].shadowMapping"); - uniforms.lightUniforms.locations.directionalSpotLightShadowMap = shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; @@ -939,6 +1075,105 @@ namespace Nz m_shaderUniforms.erase(shader); } + /*! + * \brief Sends the uniforms for light + * + * \param shader Shader to send uniforms to + * \param uniforms Uniforms to send + * \param index Index of the light + * \param uniformOffset Offset for the uniform + * \param availableTextureUnit Unit texture available + */ + void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int lightIndex, unsigned int uniformOffset) const + { + if (lightIndex < m_lights.size()) + { + const LightIndex& lightInfo = m_lights[lightIndex]; + + shader->SendInteger(uniforms.locations.type + uniformOffset, lightInfo.type); //< Sends the light type + + switch (lightInfo.type) + { + case LightType_Directional: + { + const auto& light = m_renderQueue.directionalLights[lightInfo.index]; + + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); + + if (uniforms.locations.shadowMapping != -1) + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + + if (light.shadowMap) + { + unsigned int textureUnit2D = Material::GetTextureUnit(static_cast(TextureMap_Shadow2D_1 + index)); + + Renderer::SetTexture(textureUnit2D, light.shadowMap); + Renderer::SetTextureSampler(textureUnit2D, s_shadowSampler); + + if (uniforms.locations.lightViewProjMatrix != -1) + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + } + break; + } + + case LightType_Point: + { + const auto& light = m_renderQueue.pointLights[lightInfo.index]; + + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); + shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius)); + + if (uniforms.locations.shadowMapping != -1) + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + + if (light.shadowMap) + { + unsigned int textureUnitCube = Material::GetTextureUnit(static_cast(TextureMap_ShadowCube_1 + index)); + + Renderer::SetTexture(textureUnitCube, light.shadowMap); + Renderer::SetTextureSampler(textureUnitCube, s_shadowSampler); + } + break; + } + + case LightType_Spot: + { + const auto& light = m_renderQueue.spotLights[lightInfo.index]; + + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); + shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); + shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); + + if (uniforms.locations.shadowMapping != -1) + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + + if (light.shadowMap) + { + unsigned int textureUnit2D = Material::GetTextureUnit(static_cast(TextureMap_Shadow2D_1 + index)); + + Renderer::SetTexture(textureUnit2D, light.shadowMap); + Renderer::SetTextureSampler(textureUnit2D, s_shadowSampler); + + if (uniforms.locations.lightViewProjMatrix != -1) + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + } + break; + } + } + } + else + { + if (uniforms.locations.type != -1) + shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader + } + } + IndexBuffer ForwardRenderTechnique::s_quadIndexBuffer; TextureSampler ForwardRenderTechnique::s_shadowSampler; VertexBuffer ForwardRenderTechnique::s_quadVertexBuffer; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 8f5427718..e1b202716 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 7c2122281..0699b7fcf 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/InstancedRenderable.cpp b/src/Nazara/Graphics/InstancedRenderable.cpp index e927e2d22..5eb0f17fa 100644 --- a/src/Nazara/Graphics/InstancedRenderable.cpp +++ b/src/Nazara/Graphics/InstancedRenderable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 275d78a79..a2b188006 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index b81bd82b4..0e865038a 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -36,7 +36,7 @@ namespace Nz * \param textureUnit Unit for the texture GL_TEXTURE"i" * \param lastUsedUnit Optional argument to get the last texture unit */ - void Material::Apply(const MaterialPipeline::Instance& instance, UInt8 textureUnit, UInt8* lastUsedUnit) const + void Material::Apply(const MaterialPipeline::Instance& instance) const { const Shader* shader = instance.renderPipeline.GetInfo().shader; @@ -57,54 +57,51 @@ namespace Nz if (m_alphaMap && instance.uniforms[MaterialUniform_AlphaMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Alpha]; + Renderer::SetTexture(textureUnit, m_alphaMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], textureUnit); - textureUnit++; } if (m_diffuseMap && instance.uniforms[MaterialUniform_DiffuseMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Diffuse]; + Renderer::SetTexture(textureUnit, m_diffuseMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], textureUnit); - textureUnit++; } if (m_emissiveMap && instance.uniforms[MaterialUniform_EmissiveMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Emissive]; + Renderer::SetTexture(textureUnit, m_emissiveMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], textureUnit); - textureUnit++; } if (m_heightMap && instance.uniforms[MaterialUniform_HeightMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Height]; + Renderer::SetTexture(textureUnit, m_heightMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], textureUnit); - textureUnit++; } if (m_normalMap && instance.uniforms[MaterialUniform_NormalMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Normal]; + Renderer::SetTexture(textureUnit, m_normalMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], textureUnit); - textureUnit++; } if (m_specularMap && instance.uniforms[MaterialUniform_SpecularMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Specular]; + Renderer::SetTexture(textureUnit, m_specularMap); Renderer::SetTextureSampler(textureUnit, m_specularSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], textureUnit); - textureUnit++; } - - if (lastUsedUnit) - *lastUsedUnit = textureUnit; } /*! @@ -117,14 +114,14 @@ namespace Nz { Color color; bool isEnabled; - float fValue; - int iValue; + double dValue; + long long iValue; String path; ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true); - if (matData.GetFloatParameter(MaterialData::AlphaThreshold, &fValue)) - SetAlphaThreshold(fValue); + if (matData.GetDoubleParameter(MaterialData::AlphaThreshold, &dValue)) + SetAlphaThreshold(float(dValue)); if (matData.GetBooleanParameter(MaterialData::AlphaTest, &isEnabled)) EnableAlphaTest(isEnabled); @@ -150,17 +147,17 @@ namespace Nz if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue)) SetFaceFilling(static_cast(iValue)); - if (matData.GetFloatParameter(MaterialData::LineWidth, &fValue)) - SetLineWidth(fValue); + if (matData.GetDoubleParameter(MaterialData::LineWidth, &dValue)) + SetLineWidth(float(dValue)); - if (matData.GetFloatParameter(MaterialData::PointSize, &fValue)) - SetPointSize(fValue); + if (matData.GetDoubleParameter(MaterialData::PointSize, &dValue)) + SetPointSize(float(dValue)); if (matData.GetColorParameter(MaterialData::SpecularColor, &color)) SetSpecularColor(color); - if (matData.GetFloatParameter(MaterialData::Shininess, &fValue)) - SetShininess(fValue); + if (matData.GetDoubleParameter(MaterialData::Shininess, &dValue)) + SetShininess(float(dValue)); if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue)) SetSrcBlend(static_cast(iValue)); @@ -280,17 +277,17 @@ namespace Nz matData->SetParameter(MaterialData::AlphaTest, IsAlphaTestEnabled()); matData->SetParameter(MaterialData::AlphaThreshold, GetAlphaThreshold()); matData->SetParameter(MaterialData::AmbientColor, GetAmbientColor()); - matData->SetParameter(MaterialData::CullingSide, int(GetFaceCulling())); - matData->SetParameter(MaterialData::DepthFunc, int(GetDepthFunc())); + matData->SetParameter(MaterialData::CullingSide, static_cast(GetFaceCulling())); + matData->SetParameter(MaterialData::DepthFunc, static_cast(GetDepthFunc())); matData->SetParameter(MaterialData::DepthSorting, IsDepthSortingEnabled()); matData->SetParameter(MaterialData::DiffuseColor, GetDiffuseColor()); - matData->SetParameter(MaterialData::DstBlend, int(GetDstBlend())); - matData->SetParameter(MaterialData::FaceFilling, int(GetFaceFilling())); + matData->SetParameter(MaterialData::DstBlend, static_cast(GetDstBlend())); + matData->SetParameter(MaterialData::FaceFilling, static_cast(GetFaceFilling())); matData->SetParameter(MaterialData::LineWidth, GetLineWidth()); matData->SetParameter(MaterialData::PointSize, GetPointSize()); matData->SetParameter(MaterialData::Shininess, GetShininess()); matData->SetParameter(MaterialData::SpecularColor, GetSpecularColor()); - matData->SetParameter(MaterialData::SrcBlend, int(GetSrcBlend())); + matData->SetParameter(MaterialData::SrcBlend, static_cast(GetSrcBlend())); // RendererParameter matData->SetParameter(MaterialData::Blending, IsBlendingEnabled()); @@ -302,29 +299,29 @@ namespace Nz matData->SetParameter(MaterialData::StencilTest, IsStencilTestEnabled()); // Samplers - matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, int(GetDiffuseSampler().GetAnisotropicLevel())); - matData->SetParameter(MaterialData::DiffuseFilter, int(GetDiffuseSampler().GetFilterMode())); - matData->SetParameter(MaterialData::DiffuseWrap, int(GetDiffuseSampler().GetWrapMode())); + matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, static_cast(GetDiffuseSampler().GetAnisotropicLevel())); + matData->SetParameter(MaterialData::DiffuseFilter, static_cast(GetDiffuseSampler().GetFilterMode())); + matData->SetParameter(MaterialData::DiffuseWrap, static_cast(GetDiffuseSampler().GetWrapMode())); - matData->SetParameter(MaterialData::SpecularAnisotropyLevel, int(GetSpecularSampler().GetAnisotropicLevel())); - matData->SetParameter(MaterialData::SpecularFilter, int(GetSpecularSampler().GetFilterMode())); - matData->SetParameter(MaterialData::SpecularWrap, int(GetSpecularSampler().GetWrapMode())); + matData->SetParameter(MaterialData::SpecularAnisotropyLevel, static_cast(GetSpecularSampler().GetAnisotropicLevel())); + matData->SetParameter(MaterialData::SpecularFilter, static_cast(GetSpecularSampler().GetFilterMode())); + matData->SetParameter(MaterialData::SpecularWrap, static_cast(GetSpecularSampler().GetWrapMode())); // Stencil - matData->SetParameter(MaterialData::StencilCompare, int(GetPipelineInfo().stencilCompare.front)); - matData->SetParameter(MaterialData::StencilFail, int(GetPipelineInfo().stencilFail.front)); - matData->SetParameter(MaterialData::StencilPass, int(GetPipelineInfo().stencilPass.front)); - matData->SetParameter(MaterialData::StencilZFail, int(GetPipelineInfo().stencilDepthFail.front)); - matData->SetParameter(MaterialData::StencilMask, int(GetPipelineInfo().stencilWriteMask.front)); - matData->SetParameter(MaterialData::StencilReference, int(GetPipelineInfo().stencilReference.front)); + matData->SetParameter(MaterialData::StencilCompare, static_cast(GetPipelineInfo().stencilCompare.front)); + matData->SetParameter(MaterialData::StencilFail, static_cast(GetPipelineInfo().stencilFail.front)); + matData->SetParameter(MaterialData::StencilPass, static_cast(GetPipelineInfo().stencilPass.front)); + matData->SetParameter(MaterialData::StencilZFail, static_cast(GetPipelineInfo().stencilDepthFail.front)); + matData->SetParameter(MaterialData::StencilMask, static_cast(GetPipelineInfo().stencilWriteMask.front)); + matData->SetParameter(MaterialData::StencilReference, static_cast(GetPipelineInfo().stencilReference.front)); // Stencil (back) - matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetPipelineInfo().stencilCompare.back)); - matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetPipelineInfo().stencilFail.back)); - matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetPipelineInfo().stencilPass.back)); - matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetPipelineInfo().stencilDepthFail.back)); - matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetPipelineInfo().stencilWriteMask.back)); - matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetPipelineInfo().stencilReference.back)); + matData->SetParameter(MaterialData::BackFaceStencilCompare, static_cast(GetPipelineInfo().stencilCompare.back)); + matData->SetParameter(MaterialData::BackFaceStencilFail, static_cast(GetPipelineInfo().stencilFail.back)); + matData->SetParameter(MaterialData::BackFaceStencilPass, static_cast(GetPipelineInfo().stencilPass.back)); + matData->SetParameter(MaterialData::BackFaceStencilZFail, static_cast(GetPipelineInfo().stencilDepthFail.back)); + matData->SetParameter(MaterialData::BackFaceStencilMask, static_cast(GetPipelineInfo().stencilWriteMask.back)); + matData->SetParameter(MaterialData::BackFaceStencilReference, static_cast(GetPipelineInfo().stencilReference.back)); // Textures if (HasAlphaMap()) @@ -459,6 +456,23 @@ namespace Nz s_defaultMaterial->SetFaceFilling(FaceFilling_Line); MaterialLibrary::Register("Default", s_defaultMaterial); + unsigned int textureUnit = 0; + + s_textureUnits[TextureMap_Diffuse] = textureUnit++; + s_textureUnits[TextureMap_Alpha] = textureUnit++; + s_textureUnits[TextureMap_Specular] = textureUnit++; + s_textureUnits[TextureMap_Normal] = textureUnit++; + s_textureUnits[TextureMap_Emissive] = textureUnit++; + s_textureUnits[TextureMap_Overlay] = textureUnit++; + s_textureUnits[TextureMap_ReflectionCube] = textureUnit++; + s_textureUnits[TextureMap_Height] = textureUnit++; + s_textureUnits[TextureMap_Shadow2D_1] = textureUnit++; + s_textureUnits[TextureMap_ShadowCube_1] = textureUnit++; + s_textureUnits[TextureMap_Shadow2D_2] = textureUnit++; + s_textureUnits[TextureMap_ShadowCube_2] = textureUnit++; + s_textureUnits[TextureMap_Shadow2D_3] = textureUnit++; + s_textureUnits[TextureMap_ShadowCube_3] = textureUnit++; + return true; } @@ -473,6 +487,7 @@ namespace Nz MaterialLibrary::Uninitialize(); } + std::array Material::s_textureUnits; MaterialLibrary::LibraryMap Material::s_library; MaterialLoader::LoaderList Material::s_loaders; MaterialManager::ManagerMap Material::s_managerMap; diff --git a/src/Nazara/Graphics/MaterialPipeline.cpp b/src/Nazara/Graphics/MaterialPipeline.cpp index 07865c4cd..e9a100ad2 100644 --- a/src/Nazara/Graphics/MaterialPipeline.cpp +++ b/src/Nazara/Graphics/MaterialPipeline.cpp @@ -1,14 +1,11 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp #include - -#ifndef NAZARA_RENDERER_OPENGL -#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers -#endif - -#include +#include +#include +#include #include #include @@ -31,6 +28,27 @@ namespace Nz const UInt8 r_phongLightingVertexShader[] = { #include }; + + void OverrideShader(const String& path, String* source) + { + ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + + File shaderFile(path, Nz::OpenMode_ReadOnly | Nz::OpenMode_Text); + if (shaderFile.IsOpen()) + { + StringStream shaderSource; + + while (!shaderFile.EndOfFile()) + { + shaderSource << shaderFile.ReadLine(); + shaderSource << '\n'; + } + + *source = shaderSource; + + NazaraNotice(path + " will be used to override built-in shader"); + } + } } /*! @@ -106,6 +124,25 @@ namespace Nz CacheUniform(SpecularMap); #undef CacheUniform + + // Send texture units (those never changes) + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], Material::GetTextureUnit(TextureMap_Alpha)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], Material::GetTextureUnit(TextureMap_Diffuse)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], Material::GetTextureUnit(TextureMap_Emissive)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], Material::GetTextureUnit(TextureMap_Height)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], Material::GetTextureUnit(TextureMap_Normal)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], Material::GetTextureUnit(TextureMap_Specular)); + + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("ReflectionMap"), Material::GetTextureUnit(TextureMap_ReflectionCube)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("TextureOverlay"), Material::GetTextureUnit(TextureMap_Overlay)); + + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"), Material::GetTextureUnit(TextureMap_Shadow2D_1)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[1]"), Material::GetTextureUnit(TextureMap_Shadow2D_2)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[2]"), Material::GetTextureUnit(TextureMap_Shadow2D_3)); + + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[0]"), Material::GetTextureUnit(TextureMap_ShadowCube_1)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[1]"), Material::GetTextureUnit(TextureMap_ShadowCube_2)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[2]"), Material::GetTextureUnit(TextureMap_ShadowCube_3)); } bool MaterialPipeline::Initialize() @@ -117,6 +154,11 @@ namespace Nz String fragmentShader(reinterpret_cast(r_basicFragmentShader), sizeof(r_basicFragmentShader)); String vertexShader(reinterpret_cast(r_basicVertexShader), sizeof(r_basicVertexShader)); + #ifdef NAZARA_DEBUG + OverrideShader("Shaders/Basic/core.frag", &fragmentShader); + OverrideShader("Shaders/Basic/core.vert", &vertexShader); + #endif + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); @@ -130,6 +172,11 @@ namespace Nz String fragmentShader(reinterpret_cast(r_phongLightingFragmentShader), sizeof(r_phongLightingFragmentShader)); String vertexShader(reinterpret_cast(r_phongLightingVertexShader), sizeof(r_phongLightingVertexShader)); + #ifdef NAZARA_DEBUG + OverrideShader("Shaders/PhongLighting/core.frag", &fragmentShader); + OverrideShader("Shaders/PhongLighting/core.vert", &vertexShader); + #endif + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING NORMAL_MAPPING PARALLAX_MAPPING SHADOW_MAPPING SPECULAR_MAPPING"); uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); @@ -150,6 +197,7 @@ namespace Nz pipelineInfo.blending = true; pipelineInfo.depthWrite = false; pipelineInfo.faceCulling = false; + pipelineInfo.depthSorting = true; pipelineInfo.dstBlend = BlendFunc_InvSrcAlpha; pipelineInfo.srcBlend = BlendFunc_SrcAlpha; @@ -160,6 +208,7 @@ namespace Nz pipelineInfo.depthBuffer = true; pipelineInfo.depthWrite = false; pipelineInfo.faceCulling = false; + pipelineInfo.depthSorting = true; pipelineInfo.dstBlend = BlendFunc_InvSrcAlpha; pipelineInfo.srcBlend = BlendFunc_SrcAlpha; @@ -178,4 +227,4 @@ namespace Nz MaterialPipelineLibrary::LibraryMap MaterialPipeline::s_library; MaterialPipeline::PipelineCache MaterialPipeline::s_pipelineCache; -} \ No newline at end of file +} diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index d382c77d9..a8e277d68 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleController.cpp b/src/Nazara/Graphics/ParticleController.cpp index d46bb1621..ab94bae69 100644 --- a/src/Nazara/Graphics/ParticleController.cpp +++ b/src/Nazara/Graphics/ParticleController.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index 60786c1f1..63b329aa4 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 038e69ce9..89811dd53 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleFunctionController.cpp b/src/Nazara/Graphics/ParticleFunctionController.cpp index 9b300f450..0519d08cc 100644 --- a/src/Nazara/Graphics/ParticleFunctionController.cpp +++ b/src/Nazara/Graphics/ParticleFunctionController.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleFunctionGenerator.cpp b/src/Nazara/Graphics/ParticleFunctionGenerator.cpp index 67d43770d..649fc1c12 100644 --- a/src/Nazara/Graphics/ParticleFunctionGenerator.cpp +++ b/src/Nazara/Graphics/ParticleFunctionGenerator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleFunctionRenderer.cpp b/src/Nazara/Graphics/ParticleFunctionRenderer.cpp index 36dfea3df..779dc4e6d 100644 --- a/src/Nazara/Graphics/ParticleFunctionRenderer.cpp +++ b/src/Nazara/Graphics/ParticleFunctionRenderer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleGenerator.cpp b/src/Nazara/Graphics/ParticleGenerator.cpp index 304a99e8c..edb745e99 100644 --- a/src/Nazara/Graphics/ParticleGenerator.cpp +++ b/src/Nazara/Graphics/ParticleGenerator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleGroup.cpp b/src/Nazara/Graphics/ParticleGroup.cpp index f2c46d91c..34a46089b 100644 --- a/src/Nazara/Graphics/ParticleGroup.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -39,10 +39,10 @@ namespace Nz */ ParticleGroup::ParticleGroup(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration) : - m_declaration(std::move(declaration)), - m_processing(false), m_maxParticleCount(maxParticleCount), - m_particleCount(0) + m_particleCount(0), + m_declaration(std::move(declaration)), + m_processing(false) { // In case of error, the constructor can only throw an exception ErrorFlags flags(ErrorFlag_ThrowException, true); @@ -60,14 +60,14 @@ namespace Nz ParticleGroup::ParticleGroup(const ParticleGroup& system) : Renderable(system), + m_maxParticleCount(system.m_maxParticleCount), + m_particleCount(system.m_particleCount), + m_particleSize(system.m_particleSize), m_controllers(system.m_controllers), m_generators(system.m_generators), m_declaration(system.m_declaration), m_renderer(system.m_renderer), - m_processing(false), - m_maxParticleCount(system.m_maxParticleCount), - m_particleCount(system.m_particleCount), - m_particleSize(system.m_particleSize) + m_processing(false) { ErrorFlags flags(ErrorFlag_ThrowException, true); diff --git a/src/Nazara/Graphics/ParticleMapper.cpp b/src/Nazara/Graphics/ParticleMapper.cpp index 27a4b4075..05932abaa 100644 --- a/src/Nazara/Graphics/ParticleMapper.cpp +++ b/src/Nazara/Graphics/ParticleMapper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/ParticleRenderer.cpp b/src/Nazara/Graphics/ParticleRenderer.cpp index e5fa56c74..9195d05ae 100644 --- a/src/Nazara/Graphics/ParticleRenderer.cpp +++ b/src/Nazara/Graphics/ParticleRenderer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index 8298245b7..5dc3c66cd 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Renderable.cpp b/src/Nazara/Graphics/Renderable.cpp index 5b02cd5cb..28a487209 100644 --- a/src/Nazara/Graphics/Renderable.cpp +++ b/src/Nazara/Graphics/Renderable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b91ac0076..b571cb9dc 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index 7391eeea6..3472238b9 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index 4a646bdbe..0a2459b7f 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index d23fe4122..04e648991 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 5b3eb2cf6..70975929f 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index a990f4af6..cd6c68c05 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Graphics/TileMap.cpp b/src/Nazara/Graphics/TileMap.cpp index ab035a7e4..7fe358fb8 100644 --- a/src/Nazara/Graphics/TileMap.cpp +++ b/src/Nazara/Graphics/TileMap.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Lua/Debug/NewOverload.cpp b/src/Nazara/Lua/Debug/NewOverload.cpp index e7cf94bd6..8c83e037e 100644 --- a/src/Nazara/Lua/Debug/NewOverload.cpp +++ b/src/Nazara/Lua/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Lua/Lua.cpp b/src/Nazara/Lua/Lua.cpp index 9b53443e7..83ec20a86 100644 --- a/src/Nazara/Lua/Lua.cpp +++ b/src/Nazara/Lua/Lua.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Lua/LuaCoroutine.cpp b/src/Nazara/Lua/LuaCoroutine.cpp new file mode 100644 index 000000000..197244134 --- /dev/null +++ b/src/Nazara/Lua/LuaCoroutine.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2017 Jérôme Leclercq +// 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 + +namespace Nz +{ + LuaCoroutine::LuaCoroutine(lua_State* internalState, int refIndex) : + LuaState(internalState), + m_ref(refIndex) + { + } + + LuaCoroutine::~LuaCoroutine() + { + if (m_ref >= 0) + DestroyReference(m_ref); + } + + bool LuaCoroutine::CanResume() const + { + return lua_status(m_state) == LUA_YIELD; + } + + Ternary LuaCoroutine::Resume(unsigned int argCount) + { + LuaInstance& instance = GetInstance(m_state); + if (instance.m_level++ == 0) + instance.m_clock.Restart(); + + int status = lua_resume(m_state, nullptr, argCount); + instance.m_level--; + + if (status == LUA_OK) + return Ternary_True; + else if (status == LUA_YIELD) + return Ternary_Unknown; + else + { + m_lastError = ToString(-1); + Pop(); + return Ternary_False; + } + } + + bool LuaCoroutine::Run(int argCount, int /*resultCount*/) + { + return Resume(argCount) != Ternary_False; + } +} diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 5162645b2..cd47ac5c7 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -21,117 +22,16 @@ namespace Nz { namespace { - LuaType FromLuaType(int type) + int AtPanic(lua_State* internalState) { - switch (type) - { - case LUA_TBOOLEAN: - return LuaType_Boolean; - - case LUA_TFUNCTION: - return LuaType_Function; - - case LUA_TLIGHTUSERDATA: - return LuaType_LightUserdata; - - case LUA_TNIL: - return LuaType_Nil; - - case LUA_TNONE: - return LuaType_None; - - case LUA_TNUMBER: - return LuaType_Number; - - case LUA_TSTRING: - return LuaType_String; - - case LUA_TTABLE: - return LuaType_Table; - - case LUA_TTHREAD: - return LuaType_Thread; - - case LUA_TUSERDATA: - return LuaType_Userdata; - - default: - return LuaType_None; - } - } - - struct StreamData - { - Stream* stream; - char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; - }; - - int AtPanic(lua_State* state) - { - String lastError(lua_tostring(state, -1)); + String lastError(lua_tostring(internalState, -1)); throw std::runtime_error("Lua panic: " + lastError); } - - const char* StreamReader(lua_State* state, void* data, std::size_t* size) - { - NazaraUnused(state); - - StreamData* streamData = static_cast(data); - - if (streamData->stream->EndOfStream()) - return nullptr; - else - { - *size = streamData->stream->Read(streamData->buffer, NAZARA_CORE_FILE_BUFFERSIZE); - return streamData->buffer; - } - } - - int s_comparisons[] = { - LUA_OPEQ, // LuaComparison_Equality - LUA_OPLT, // LuaComparison_Less - LUA_OPLE // LuaComparison_LessOrEqual - }; - - static_assert(sizeof(s_comparisons)/sizeof(int) == LuaComparison_Max+1, "Lua comparison array is incomplete"); - - int s_operations[] = { - LUA_OPADD, // LuaOperation_Addition - LUA_OPBAND, // LuaOperation_BitwiseAnd - LUA_OPSHL, // LuaOperation_BitwiseLeftShift - LUA_OPBNOT, // LuaOperation_BitwiseNot - LUA_OPBOR, // LuaOperation_BitwiseOr - LUA_OPSHR, // LuaOperation_BitwiseRightShift - LUA_OPBXOR, // LuaOperation_BitwiseXOr - LUA_OPDIV, // LuaOperation_Division - LUA_OPPOW, // LuaOperation_Exponentiation - LUA_OPIDIV, // LuaOperation_FloorDivision - LUA_OPMUL, // LuaOperation_Multiplication - LUA_OPMOD, // LuaOperation_Modulo - LUA_OPUNM, // LuaOperation_Negation - LUA_OPSUB // LuaOperation_Substraction - }; - - static_assert(sizeof(s_operations)/sizeof(int) == LuaOperation_Max+1, "Lua operation array is incomplete"); - - int s_types[] = { - LUA_TBOOLEAN, // LuaType_Boolean - LUA_TFUNCTION, // LuaType_Function - LUA_TLIGHTUSERDATA, // LuaType_LightUserdata - LUA_TNIL, // LuaType_Nil - LUA_TNUMBER, // LuaType_Number - LUA_TNONE, // LuaType_None - LUA_TSTRING, // LuaType_String - LUA_TTABLE, // LuaType_Table - LUA_TTHREAD, // LuaType_Thread - LUA_TUSERDATA // LuaType_Userdata - }; - - static_assert(sizeof(s_types)/sizeof(int) == LuaType_Max+1, "Lua type array is incomplete"); } LuaInstance::LuaInstance() : + LuaState(nullptr), m_memoryLimit(0), m_memoryUsage(0), m_timeLimit(1000), @@ -149,700 +49,22 @@ namespace Nz lua_close(m_state); } - void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const char* error) const + inline void LuaInstance::SetMemoryUsage(std::size_t memoryUsage) { - luaL_argcheck(m_state, condition, argNum, error); - } - - void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const String& error) const - { - luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer()); - } - - int LuaInstance::ArgError(unsigned int argNum, const char* error) const - { - return luaL_argerror(m_state, argNum, error); - } - - int LuaInstance::ArgError(unsigned int argNum, const String& error) const - { - return luaL_argerror(m_state, argNum, error.GetConstBuffer()); - } - - bool LuaInstance::Call(unsigned int argCount) - { - return Run(argCount, LUA_MULTRET); - } - - bool LuaInstance::Call(unsigned int argCount, unsigned int resultCount) - { - return Run(argCount, resultCount); - } - - void LuaInstance::CheckAny(int index) const - { - luaL_checkany(m_state, index); - } - - bool LuaInstance::CheckBoolean(int index) const - { - if (lua_isnoneornil(m_state, index)) - { - const char* msg = lua_pushfstring(m_state, "%s expected, got %s", lua_typename(m_state, LUA_TBOOLEAN), luaL_typename(m_state, index)); - luaL_argerror(m_state, index, msg); // Lance une exception - return false; - } - - return lua_toboolean(m_state, index) != 0; - } - - bool LuaInstance::CheckBoolean(int index, bool defValue) const - { - if (lua_isnoneornil(m_state, index)) - return defValue; - - return lua_toboolean(m_state, index) != 0; - } - - long long LuaInstance::CheckInteger(int index) const - { - return luaL_checkinteger(m_state, index); - } - - long long LuaInstance::CheckInteger(int index, long long defValue) const - { - return luaL_optinteger(m_state, index, defValue); - } - - double LuaInstance::CheckNumber(int index) const - { - return luaL_checknumber(m_state, index); - } - - double LuaInstance::CheckNumber(int index, double defValue) const - { - return luaL_optnumber(m_state, index, defValue); - } - - void LuaInstance::CheckStack(int space, const char* error) const - { - luaL_checkstack(m_state, space, error); - } - - void LuaInstance::CheckStack(int space, const String& error) const - { - CheckStack(space, error.GetConstBuffer()); - } - - const char* LuaInstance::CheckString(int index, std::size_t* length) const - { - return luaL_checklstring(m_state, index, length); - } - - const char* LuaInstance::CheckString(int index, const char* defValue, std::size_t* length) const - { - return luaL_optlstring(m_state, index, defValue, length); - } - - void LuaInstance::CheckType(int index, LuaType type) const - { - #ifdef NAZARA_DEBUG - if (type > LuaType_Max) - { - NazaraError("Lua type out of enum"); - return; - } - #endif - - luaL_checktype(m_state, index, s_types[type]); - } - - void* LuaInstance::CheckUserdata(int index, const char* tname) const - { - return luaL_checkudata(m_state, index, tname); - } - - void* LuaInstance::CheckUserdata(int index, const String& tname) const - { - return luaL_checkudata(m_state, index, tname.GetConstBuffer()); - } - - bool LuaInstance::Compare(int index1, int index2, LuaComparison comparison) const - { - #ifdef NAZARA_DEBUG - if (comparison > LuaComparison_Max) - { - NazaraError("Lua comparison out of enum"); - return false; - } - #endif - - return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0); - } - - void LuaInstance::Compute(LuaOperation operation) const - { - #ifdef NAZARA_DEBUG - if (operation > LuaOperation_Max) - { - NazaraError("Lua operation out of enum"); - return; - } - #endif - - lua_arith(m_state, s_operations[operation]); - } - - void LuaInstance::Concatenate(int count) const - { - lua_concat(m_state, count); - } - - int LuaInstance::CreateReference() - { - return luaL_ref(m_state, LUA_REGISTRYINDEX); - } - - void LuaInstance::DestroyReference(int ref) - { - luaL_unref(m_state, LUA_REGISTRYINDEX, ref); - } - - String LuaInstance::DumpStack() const - { - StringStream stream; - unsigned int stackTop = GetStackTop(); - stream << stackTop << " entries\n"; - - for (unsigned int i = 1; i <= stackTop; ++i) - { - stream << i << ": "; - switch (GetType(i)) - { - case LuaType_Boolean: - stream << "Boolean(" << ToBoolean(i) << ')'; - break; - - case LuaType_Function: - stream << "Function(" << ToPointer(i) << ')'; - break; - - case LuaType_LightUserdata: - case LuaType_Userdata: - stream << "Userdata(" << ToUserdata(i) << ')'; - break; - - case LuaType_Nil: - stream << "Nil"; - break; - - case LuaType_None: - stream << "None"; - break; - - case LuaType_Number: - stream << "Number(" << ToNumber(i) << ')'; - break; - - case LuaType_String: - stream << "String(" << ToString(i) << ')'; - break; - - case LuaType_Table: - stream << "Table(" << ToPointer(i) << ')'; - break; - - case LuaType_Thread: - stream << "Thread(" << ToPointer(i) << ')'; - break; - - default: - stream << "Unknown(" << ToPointer(i) << ')'; - break; - } - - stream << '\n'; - } - - return stream.ToString(); - } - - void LuaInstance::Error(const char* message) const - { - luaL_error(m_state, message); - } - - void LuaInstance::Error(const String& message) const - { - luaL_error(m_state, message.GetConstBuffer()); - } - - bool LuaInstance::Execute(const String& code) - { - if (code.IsEmpty()) - return true; - - if (luaL_loadstring(m_state, code.GetConstBuffer()) != 0) - { - m_lastError = lua_tostring(m_state, -1); - lua_pop(m_state, 1); - - return false; - } - - return Run(0, 0); - } - - bool LuaInstance::ExecuteFromFile(const String& filePath) - { - File file(filePath); - if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) - { - NazaraError("Failed to open file"); - return false; - } - - std::size_t length = static_cast(file.GetSize()); - - String source(length, '\0'); - - if (file.Read(&source[0], length) != length) - { - NazaraError("Failed to read file"); - return false; - } - - file.Close(); - - return Execute(source); - } - - bool LuaInstance::ExecuteFromMemory(const void* data, std::size_t size) - { - MemoryView stream(data, size); - return ExecuteFromStream(stream); - } - - bool LuaInstance::ExecuteFromStream(Stream& stream) - { - StreamData data; - data.stream = &stream; - - if (lua_load(m_state, StreamReader, &data, "C++", nullptr) != 0) - { - m_lastError = lua_tostring(m_state, -1); - lua_pop(m_state, 1); - - return false; - } - - return Run(0, 0); - } - - int LuaInstance::GetAbsIndex(int index) const - { - return lua_absindex(m_state, index); - } - - LuaType LuaInstance::GetField(const char* fieldName, int tableIndex) const - { - return FromLuaType(lua_getfield(m_state, tableIndex, fieldName)); - } - - LuaType LuaInstance::GetField(const String& fieldName, int tableIndex) const - { - return FromLuaType(lua_getfield(m_state, tableIndex, fieldName.GetConstBuffer())); - } - - LuaType LuaInstance::GetGlobal(const char* name) const - { - return FromLuaType(lua_getglobal(m_state, name)); - } - - LuaType LuaInstance::GetGlobal(const String& name) const - { - return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer())); - } - - LuaType LuaInstance::GetMetatable(const char* tname) const - { - return FromLuaType(luaL_getmetatable(m_state, tname)); - } - - LuaType LuaInstance::GetMetatable(const String& tname) const - { - return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer())); - } - - bool LuaInstance::GetMetatable(int index) const - { - return lua_getmetatable(m_state, index) != 0; - } - - unsigned int LuaInstance::GetStackTop() const - { - return static_cast(lua_gettop(m_state)); - } - - LuaType LuaInstance::GetTable(int index) const - { - return FromLuaType(lua_gettable(m_state, index)); - } - - LuaType LuaInstance::GetType(int index) const - { - return FromLuaType(lua_type(m_state, index)); - } - - const char* LuaInstance::GetTypeName(LuaType type) const - { - #ifdef NAZARA_DEBUG - if (type > LuaType_Max) - { - NazaraError("Lua type out of enum"); - return nullptr; - } - #endif - - return lua_typename(m_state, s_types[type]); - } - - void LuaInstance::Insert(int index) const - { - lua_insert(m_state, index); - } - - bool LuaInstance::IsOfType(int index, LuaType type) const - { - switch (type) - { - case LuaType_Boolean: - return lua_isboolean(m_state, index) != 0; - - case LuaType_Function: - return lua_isfunction(m_state, index) != 0; - - case LuaType_LightUserdata: - return lua_islightuserdata(m_state, index) != 0; - - case LuaType_Nil: - return lua_isnil(m_state, index) != 0; - - case LuaType_None: - return lua_isnone(m_state, index) != 0; - - case LuaType_Number: - return lua_isnumber(m_state, index) != 0; - - case LuaType_String: - return lua_isstring(m_state, index) != 0; - - case LuaType_Table: - return lua_istable(m_state, index) != 0; - - case LuaType_Thread: - return lua_isthread(m_state, index) != 0; - - case LuaType_Userdata: - return lua_isuserdata(m_state, index) != 0; - } - - NazaraError("Lua type not handled (0x" + String::Number(type, 16) + ')'); - return false; - } - - bool LuaInstance::IsOfType(int index, const char* tname) const - { - void* ud = luaL_testudata(m_state, index, tname); - return ud != nullptr; - } - - bool LuaInstance::IsOfType(int index, const String& tname) const - { - return IsOfType(index, tname.GetConstBuffer()); - } - - bool LuaInstance::IsValid(int index) const - { - return lua_isnoneornil(m_state, index) == 0; - } - - long long LuaInstance::Length(int index) const - { - return luaL_len(m_state, index); - } - - void LuaInstance::MoveTo(LuaInstance* instance, int n) const - { - lua_xmove(m_state, instance->m_state, n); - } - - bool LuaInstance::NewMetatable(const char* str) - { - return luaL_newmetatable(m_state, str) != 0; - } - - bool LuaInstance::NewMetatable(const String& str) - { - return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0; - } - - bool LuaInstance::Next(int index) const - { - return lua_next(m_state, index) != 0; - } - - void LuaInstance::Pop(unsigned int n) const - { - lua_pop(m_state, static_cast(n)); - } - - void LuaInstance::PushBoolean(bool value) const - { - lua_pushboolean(m_state, (value) ? 1 : 0); - } - - void LuaInstance::PushCFunction(LuaCFunction func, unsigned int upvalueCount) const - { - lua_pushcclosure(m_state, func, upvalueCount); - } - - void LuaInstance::PushFunction(LuaFunction func) const - { - LuaFunction* luaFunc = static_cast(lua_newuserdata(m_state, sizeof(LuaFunction))); - PlacementNew(luaFunc, std::move(func)); - - lua_pushcclosure(m_state, ProxyFunc, 1); - } - - void LuaInstance::PushInteger(long long value) const - { - lua_pushinteger(m_state, value); - } - - void LuaInstance::PushLightUserdata(void* value) const - { - lua_pushlightuserdata(m_state, value); - } - - void LuaInstance::PushMetatable(const char* str) const - { - luaL_getmetatable(m_state, str); - } - - void LuaInstance::PushMetatable(const String& str) const - { - luaL_getmetatable(m_state, str.GetConstBuffer()); - } - - void LuaInstance::PushNil() const - { - lua_pushnil(m_state); - } - - void LuaInstance::PushNumber(double value) const - { - lua_pushnumber(m_state, value); - } - - void LuaInstance::PushReference(int ref) const - { - lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref); - } - - void LuaInstance::PushString(const char* str) const - { - lua_pushstring(m_state, str); - } - - void LuaInstance::PushString(const char* str, std::size_t size) const - { - lua_pushlstring(m_state, str, size); - } - - void LuaInstance::PushString(const String& str) const - { - lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize()); - } - - void LuaInstance::PushTable(std::size_t sequenceElementCount, std::size_t arrayElementCount) const - { - constexpr std::size_t maxInt = std::numeric_limits::max(); - lua_createtable(m_state, static_cast(std::min(sequenceElementCount, maxInt)), static_cast(std::min(arrayElementCount, maxInt))); - } - - void* LuaInstance::PushUserdata(std::size_t size) const - { - return lua_newuserdata(m_state, size); - } - - void LuaInstance::PushValue(int index) const - { - lua_pushvalue(m_state, index); - } - - void LuaInstance::Remove(int index) const - { - lua_remove(m_state, index); - } - - void LuaInstance::Replace(int index) const - { - lua_replace(m_state, index); - } - - void LuaInstance::SetField(const char* name, int tableIndex) const - { - lua_setfield(m_state, tableIndex, name); - } - - void LuaInstance::SetField(const String& name, int tableIndex) const - { - lua_setfield(m_state, tableIndex, name.GetConstBuffer()); - } - - void LuaInstance::SetGlobal(const char* name) - { - lua_setglobal(m_state, name); - } - - void LuaInstance::SetGlobal(const String& name) - { - lua_setglobal(m_state, name.GetConstBuffer()); - } - - void LuaInstance::SetMetatable(const char* tname) const - { - luaL_setmetatable(m_state, tname); - } - - void LuaInstance::SetMetatable(const String& tname) const - { - luaL_setmetatable(m_state, tname.GetConstBuffer()); - } - - void LuaInstance::SetMetatable(int index) const - { - lua_setmetatable(m_state, index); - } - - void LuaInstance::SetMemoryLimit(std::size_t memoryLimit) - { - m_memoryLimit = memoryLimit; - } - - void LuaInstance::SetTable(int index) const - { - lua_settable(m_state, index); - } - - void LuaInstance::SetTimeLimit(UInt32 timeLimit) - { - if (m_timeLimit != timeLimit) - { - if (m_timeLimit == 0) - lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000); - else if (timeLimit == 0) - lua_sethook(m_state, TimeLimiter, 0, 1000); - - m_timeLimit = timeLimit; - } - } - - bool LuaInstance::ToBoolean(int index) const - { - return lua_toboolean(m_state, index) != 0; - } - - long long LuaInstance::ToInteger(int index, bool* succeeded) const - { - int success; - long long result = lua_tointegerx(m_state, index, &success); - - if (succeeded) - *succeeded = (success != 0); - - return result; - } - - double LuaInstance::ToNumber(int index, bool* succeeded) const - { - int success; - double result = lua_tonumberx(m_state, index, &success); - - if (succeeded) - *succeeded = (success != 0); - - return result; - } - - const void* LuaInstance::ToPointer(int index) const - { - return lua_topointer(m_state, index); - } - - const char* LuaInstance::ToString(int index, std::size_t* length) const - { - return lua_tolstring(m_state, index, length); - } - - void* LuaInstance::ToUserdata(int index) const - { - return lua_touserdata(m_state, index); - } - - void* LuaInstance::ToUserdata(int index, const char* tname) const - { - return luaL_testudata(m_state, index, tname); - } - - void* LuaInstance::ToUserdata(int index, const String& tname) const - { - return luaL_testudata(m_state, index, tname.GetConstBuffer()); - } - - int LuaInstance::GetIndexOfUpValue(int upValue) - { - return lua_upvalueindex(upValue); - } - - LuaInstance* LuaInstance::GetInstance(lua_State* state) - { - LuaInstance* instance; - lua_getallocf(state, reinterpret_cast(&instance)); - - return instance; - } - - bool LuaInstance::Run(int argCount, int resultCount) - { - if (m_level++ == 0) - m_clock.Restart(); - - int status = lua_pcall(m_state, argCount, resultCount, 0); - - m_level--; - - if (status != 0) - { - m_lastError = lua_tostring(m_state, -1); - lua_pop(m_state, 1); - - return false; - } - - return true; + m_memoryUsage = memoryUsage; } void* LuaInstance::MemoryAllocator(void* ud, void* ptr, std::size_t osize, std::size_t nsize) { LuaInstance* instance = static_cast(ud); - std::size_t& memoryLimit = instance->m_memoryLimit; - std::size_t& memoryUsage = instance->m_memoryUsage; + std::size_t memoryLimit = instance->GetMemoryLimit(); + std::size_t memoryUsage = instance->GetMemoryUsage(); if (nsize == 0) { - memoryUsage -= osize; + assert(memoryUsage >= osize); + + instance->SetMemoryUsage(memoryUsage - osize); std::free(ptr); return nullptr; @@ -859,24 +81,20 @@ namespace Nz return nullptr; } - memoryUsage = usage; + instance->SetMemoryUsage(usage); return std::realloc(ptr, nsize); } } - int LuaInstance::ProxyFunc(lua_State* state) - { - LuaFunction& func = *static_cast(lua_touserdata(state, lua_upvalueindex(1))); - return func(*GetInstance(state)); - } - - void LuaInstance::TimeLimiter(lua_State* state, lua_Debug* debug) + void LuaInstance::TimeLimiter(lua_State* internalState, lua_Debug* debug) { NazaraUnused(debug); - LuaInstance* instance = GetInstance(state); - if (instance->m_clock.GetMilliseconds() > instance->m_timeLimit) - luaL_error(state, "maximum execution time exceeded"); + LuaInstance* instance; + lua_getallocf(internalState, reinterpret_cast(&instance)); + + if (instance->m_clock.GetMilliseconds() > instance->GetTimeLimit()) + luaL_error(internalState, "maximum execution time exceeded"); } } diff --git a/src/Nazara/Lua/LuaState.cpp b/src/Nazara/Lua/LuaState.cpp new file mode 100644 index 000000000..4821b1d09 --- /dev/null +++ b/src/Nazara/Lua/LuaState.cpp @@ -0,0 +1,843 @@ +// Copyright (C) 2017 Jérôme Leclercq +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace + { + LuaType FromLuaType(int type) + { + switch (type) + { + case LUA_TBOOLEAN: + return LuaType_Boolean; + + case LUA_TFUNCTION: + return LuaType_Function; + + case LUA_TLIGHTUSERDATA: + return LuaType_LightUserdata; + + case LUA_TNIL: + return LuaType_Nil; + + case LUA_TNONE: + return LuaType_None; + + case LUA_TNUMBER: + return LuaType_Number; + + case LUA_TSTRING: + return LuaType_String; + + case LUA_TTABLE: + return LuaType_Table; + + case LUA_TTHREAD: + return LuaType_Thread; + + case LUA_TUSERDATA: + return LuaType_Userdata; + + default: + return LuaType_None; + } + } + + struct StreamData + { + Stream* stream; + char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; + }; + + const char* StreamReader(lua_State* internalState, void* data, std::size_t* size) + { + NazaraUnused(internalState); + + StreamData* streamData = static_cast(data); + + if (streamData->stream->EndOfStream()) + return nullptr; + else + { + *size = streamData->stream->Read(streamData->buffer, NAZARA_CORE_FILE_BUFFERSIZE); + return streamData->buffer; + } + } + + int s_comparisons[] = { + LUA_OPEQ, // LuaComparison_Equality + LUA_OPLT, // LuaComparison_Less + LUA_OPLE // LuaComparison_LessOrEqual + }; + + static_assert(sizeof(s_comparisons)/sizeof(int) == LuaComparison_Max+1, "Lua comparison array is incomplete"); + + int s_operations[] = { + LUA_OPADD, // LuaOperation_Addition + LUA_OPBAND, // LuaOperation_BitwiseAnd + LUA_OPSHL, // LuaOperation_BitwiseLeftShift + LUA_OPBNOT, // LuaOperation_BitwiseNot + LUA_OPBOR, // LuaOperation_BitwiseOr + LUA_OPSHR, // LuaOperation_BitwiseRightShift + LUA_OPBXOR, // LuaOperation_BitwiseXOr + LUA_OPDIV, // LuaOperation_Division + LUA_OPPOW, // LuaOperation_Exponentiation + LUA_OPIDIV, // LuaOperation_FloorDivision + LUA_OPMUL, // LuaOperation_Multiplication + LUA_OPMOD, // LuaOperation_Modulo + LUA_OPUNM, // LuaOperation_Negation + LUA_OPSUB // LuaOperation_Substraction + }; + + static_assert(sizeof(s_operations)/sizeof(int) == LuaOperation_Max+1, "Lua operation array is incomplete"); + + int s_types[] = { + LUA_TBOOLEAN, // LuaType_Boolean + LUA_TFUNCTION, // LuaType_Function + LUA_TLIGHTUSERDATA, // LuaType_LightUserdata + LUA_TNIL, // LuaType_Nil + LUA_TNUMBER, // LuaType_Number + LUA_TNONE, // LuaType_None + LUA_TSTRING, // LuaType_String + LUA_TTABLE, // LuaType_Table + LUA_TTHREAD, // LuaType_Thread + LUA_TUSERDATA // LuaType_Userdata + }; + + static_assert(sizeof(s_types)/sizeof(int) == LuaType_Max+1, "Lua type array is incomplete"); + } + + LuaState::LuaState(LuaState&& state) noexcept : + m_lastError(state.m_lastError), + m_state(state.m_state) + { + } + + void LuaState::ArgCheck(bool condition, unsigned int argNum, const char* error) const + { + luaL_argcheck(m_state, condition, argNum, error); + } + + void LuaState::ArgCheck(bool condition, unsigned int argNum, const String& error) const + { + luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer()); + } + + int LuaState::ArgError(unsigned int argNum, const char* error) const + { + return luaL_argerror(m_state, argNum, error); + } + + int LuaState::ArgError(unsigned int argNum, const String& error) const + { + return luaL_argerror(m_state, argNum, error.GetConstBuffer()); + } + + bool LuaState::Call(unsigned int argCount) + { + return Run(argCount, LUA_MULTRET); + } + + bool LuaState::Call(unsigned int argCount, unsigned int resultCount) + { + return Run(argCount, resultCount); + } + + void LuaState::CheckAny(int index) const + { + luaL_checkany(m_state, index); + } + + bool LuaState::CheckBoolean(int index) const + { + if (lua_isnoneornil(m_state, index)) + { + const char* msg = lua_pushfstring(m_state, "%s expected, got %s", lua_typename(m_state, LUA_TBOOLEAN), luaL_typename(m_state, index)); + luaL_argerror(m_state, index, msg); // Lance une exception + return false; + } + + return lua_toboolean(m_state, index) != 0; + } + + bool LuaState::CheckBoolean(int index, bool defValue) const + { + if (lua_isnoneornil(m_state, index)) + return defValue; + + return lua_toboolean(m_state, index) != 0; + } + + long long LuaState::CheckInteger(int index) const + { + return luaL_checkinteger(m_state, index); + } + + long long LuaState::CheckInteger(int index, long long defValue) const + { + return luaL_optinteger(m_state, index, defValue); + } + + double LuaState::CheckNumber(int index) const + { + return luaL_checknumber(m_state, index); + } + + double LuaState::CheckNumber(int index, double defValue) const + { + return luaL_optnumber(m_state, index, defValue); + } + + void LuaState::CheckStack(int space, const char* error) const + { + luaL_checkstack(m_state, space, error); + } + + void LuaState::CheckStack(int space, const String& error) const + { + CheckStack(space, error.GetConstBuffer()); + } + + const char* LuaState::CheckString(int index, std::size_t* length) const + { + return luaL_checklstring(m_state, index, length); + } + + const char* LuaState::CheckString(int index, const char* defValue, std::size_t* length) const + { + return luaL_optlstring(m_state, index, defValue, length); + } + + void LuaState::CheckType(int index, LuaType type) const + { + #ifdef NAZARA_DEBUG + if (type > LuaType_Max) + { + NazaraError("Lua type out of enum"); + return; + } + #endif + + luaL_checktype(m_state, index, s_types[type]); + } + + void* LuaState::CheckUserdata(int index, const char* tname) const + { + return luaL_checkudata(m_state, index, tname); + } + + void* LuaState::CheckUserdata(int index, const String& tname) const + { + return luaL_checkudata(m_state, index, tname.GetConstBuffer()); + } + + bool LuaState::Compare(int index1, int index2, LuaComparison comparison) const + { + #ifdef NAZARA_DEBUG + if (comparison > LuaComparison_Max) + { + NazaraError("Lua comparison out of enum"); + return false; + } + #endif + + return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0); + } + + void LuaState::Compute(LuaOperation operation) const + { + #ifdef NAZARA_DEBUG + if (operation > LuaOperation_Max) + { + NazaraError("Lua operation out of enum"); + return; + } + #endif + + lua_arith(m_state, s_operations[operation]); + } + + void LuaState::Concatenate(int count) const + { + lua_concat(m_state, count); + } + + int LuaState::CreateReference() + { + return luaL_ref(m_state, LUA_REGISTRYINDEX); + } + + void LuaState::DestroyReference(int ref) + { + luaL_unref(m_state, LUA_REGISTRYINDEX, ref); + } + + String LuaState::DumpStack() const + { + StringStream stream; + unsigned int stackTop = GetStackTop(); + stream << stackTop << " entries\n"; + + for (unsigned int i = 1; i <= stackTop; ++i) + { + stream << i << ": "; + switch (GetType(i)) + { + case LuaType_Boolean: + stream << "Boolean(" << ToBoolean(i) << ')'; + break; + + case LuaType_Function: + stream << "Function(" << ToPointer(i) << ')'; + break; + + case LuaType_LightUserdata: + case LuaType_Userdata: + stream << "Userdata(" << ToUserdata(i) << ')'; + break; + + case LuaType_Nil: + stream << "Nil"; + break; + + case LuaType_None: + stream << "None"; + break; + + case LuaType_Number: + stream << "Number(" << ToNumber(i) << ')'; + break; + + case LuaType_String: + stream << "String(" << ToString(i) << ')'; + break; + + case LuaType_Table: + stream << "Table(" << ToPointer(i) << ')'; + break; + + case LuaType_Thread: + stream << "Thread(" << ToPointer(i) << ')'; + break; + + default: + stream << "Unknown(" << ToPointer(i) << ')'; + break; + } + + stream << '\n'; + } + + return stream.ToString(); + } + + void LuaState::Error(const char* message) const + { + luaL_error(m_state, message); + } + + void LuaState::Error(const String& message) const + { + luaL_error(m_state, message.GetConstBuffer()); + } + + bool LuaState::Execute(const String& code) + { + if (code.IsEmpty()) + return true; + + if (luaL_loadstring(m_state, code.GetConstBuffer()) != 0) + { + m_lastError = lua_tostring(m_state, -1); + lua_pop(m_state, 1); + + return false; + } + + return Run(0, LUA_MULTRET); + } + + bool LuaState::ExecuteFromFile(const String& filePath) + { + File file(filePath); + if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) + { + NazaraError("Failed to open file"); + return false; + } + + std::size_t length = static_cast(file.GetSize()); + + String source(length, '\0'); + + if (file.Read(&source[0], length) != length) + { + NazaraError("Failed to read file"); + return false; + } + + file.Close(); + + return Execute(source); + } + + bool LuaState::ExecuteFromMemory(const void* data, std::size_t size) + { + MemoryView stream(data, size); + return ExecuteFromStream(stream); + } + + bool LuaState::ExecuteFromStream(Stream& stream) + { + StreamData data; + data.stream = &stream; + + if (lua_load(m_state, StreamReader, &data, "C++", nullptr) != 0) + { + m_lastError = lua_tostring(m_state, -1); + lua_pop(m_state, 1); + + return false; + } + + return Run(0, LUA_MULTRET); + } + + int LuaState::GetAbsIndex(int index) const + { + return lua_absindex(m_state, index); + } + + LuaType LuaState::GetField(const char* fieldName, int tableIndex) const + { + return FromLuaType(lua_getfield(m_state, tableIndex, fieldName)); + } + + LuaType LuaState::GetField(const String& fieldName, int tableIndex) const + { + return FromLuaType(lua_getfield(m_state, tableIndex, fieldName.GetConstBuffer())); + } + + LuaType LuaState::GetGlobal(const char* name) const + { + return FromLuaType(lua_getglobal(m_state, name)); + } + + LuaType LuaState::GetGlobal(const String& name) const + { + return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer())); + } + + LuaType LuaState::GetMetatable(const char* tname) const + { + return FromLuaType(luaL_getmetatable(m_state, tname)); + } + + LuaType LuaState::GetMetatable(const String& tname) const + { + return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer())); + } + + bool LuaState::GetMetatable(int index) const + { + return lua_getmetatable(m_state, index) != 0; + } + + unsigned int LuaState::GetStackTop() const + { + return static_cast(lua_gettop(m_state)); + } + + LuaType LuaState::GetTable(int index) const + { + return FromLuaType(lua_gettable(m_state, index)); + } + + LuaType LuaState::GetTableRaw(int index) const + { + return FromLuaType(lua_rawget(m_state, index)); + } + + LuaType LuaState::GetType(int index) const + { + return FromLuaType(lua_type(m_state, index)); + } + + const char* LuaState::GetTypeName(LuaType type) const + { + #ifdef NAZARA_DEBUG + if (type > LuaType_Max) + { + NazaraError("Lua type out of enum"); + return nullptr; + } + #endif + + return lua_typename(m_state, s_types[type]); + } + + void LuaState::Insert(int index) const + { + lua_insert(m_state, index); + } + + bool LuaState::IsOfType(int index, LuaType type) const + { + switch (type) + { + case LuaType_Boolean: + return lua_isboolean(m_state, index) != 0; + + case LuaType_Function: + return lua_isfunction(m_state, index) != 0; + + case LuaType_LightUserdata: + return lua_islightuserdata(m_state, index) != 0; + + case LuaType_Nil: + return lua_isnil(m_state, index) != 0; + + case LuaType_None: + return lua_isnone(m_state, index) != 0; + + case LuaType_Number: + return lua_isnumber(m_state, index) != 0; + + case LuaType_String: + return lua_isstring(m_state, index) != 0; + + case LuaType_Table: + return lua_istable(m_state, index) != 0; + + case LuaType_Thread: + return lua_isthread(m_state, index) != 0; + + case LuaType_Userdata: + return lua_isuserdata(m_state, index) != 0; + } + + NazaraError("Lua type not handled (0x" + String::Number(type, 16) + ')'); + return false; + } + + bool LuaState::IsOfType(int index, const char* tname) const + { + void* ud = luaL_testudata(m_state, index, tname); + return ud != nullptr; + } + + bool LuaState::IsOfType(int index, const String& tname) const + { + return IsOfType(index, tname.GetConstBuffer()); + } + + bool LuaState::IsValid(int index) const + { + return lua_isnoneornil(m_state, index) == 0; + } + + long long LuaState::Length(int index) const + { + return luaL_len(m_state, index); + } + + std::size_t LuaState::LengthRaw(int index) const + { + return lua_rawlen(m_state, index); + } + + void LuaState::MoveTo(LuaState* instance, int n) const + { + lua_xmove(m_state, instance->m_state, n); + } + + LuaCoroutine LuaState::NewCoroutine() + { + lua_State* thread = lua_newthread(m_state); + int ref = luaL_ref(m_state, LUA_REGISTRYINDEX); + + return LuaCoroutine(thread, ref); + } + + bool LuaState::NewMetatable(const char* str) + { + return luaL_newmetatable(m_state, str) != 0; + } + + bool LuaState::NewMetatable(const String& str) + { + return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0; + } + + bool LuaState::Next(int index) const + { + return lua_next(m_state, index) != 0; + } + + void LuaState::Pop(unsigned int n) const + { + lua_pop(m_state, static_cast(n)); + } + + void LuaState::PushBoolean(bool value) const + { + lua_pushboolean(m_state, (value) ? 1 : 0); + } + + void LuaState::PushCFunction(LuaCFunction func, unsigned int upvalueCount) const + { + lua_pushcclosure(m_state, func, upvalueCount); + } + + void LuaState::PushFunction(LuaFunction func) const + { + LuaFunction* luaFunc = static_cast(lua_newuserdata(m_state, sizeof(LuaFunction))); + PlacementNew(luaFunc, std::move(func)); + + lua_pushcclosure(m_state, ProxyFunc, 1); + } + + void LuaState::PushInteger(long long value) const + { + lua_pushinteger(m_state, value); + } + + void LuaState::PushLightUserdata(void* value) const + { + lua_pushlightuserdata(m_state, value); + } + + void LuaState::PushMetatable(const char* str) const + { + luaL_getmetatable(m_state, str); + } + + void LuaState::PushMetatable(const String& str) const + { + luaL_getmetatable(m_state, str.GetConstBuffer()); + } + + void LuaState::PushNil() const + { + lua_pushnil(m_state); + } + + void LuaState::PushNumber(double value) const + { + lua_pushnumber(m_state, value); + } + + void LuaState::PushReference(int ref) const + { + lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref); + } + + void LuaState::PushString(const char* str) const + { + lua_pushstring(m_state, str); + } + + void LuaState::PushString(const char* str, std::size_t size) const + { + lua_pushlstring(m_state, str, size); + } + + void LuaState::PushString(const String& str) const + { + lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize()); + } + + void LuaState::PushTable(std::size_t sequenceElementCount, std::size_t arrayElementCount) const + { + constexpr std::size_t maxInt = std::numeric_limits::max(); + lua_createtable(m_state, static_cast(std::min(sequenceElementCount, maxInt)), static_cast(std::min(arrayElementCount, maxInt))); + } + + void* LuaState::PushUserdata(std::size_t size) const + { + return lua_newuserdata(m_state, size); + } + + void LuaState::PushValue(int index) const + { + lua_pushvalue(m_state, index); + } + + void LuaState::Remove(int index) const + { + lua_remove(m_state, index); + } + + void LuaState::Replace(int index) const + { + lua_replace(m_state, index); + } + + void LuaState::SetField(const char* name, int tableIndex) const + { + lua_setfield(m_state, tableIndex, name); + } + + void LuaState::SetField(const String& name, int tableIndex) const + { + lua_setfield(m_state, tableIndex, name.GetConstBuffer()); + } + + void LuaState::SetGlobal(const char* name) + { + lua_setglobal(m_state, name); + } + + void LuaState::SetGlobal(const String& name) + { + lua_setglobal(m_state, name.GetConstBuffer()); + } + + void LuaState::SetMetatable(const char* tname) const + { + luaL_setmetatable(m_state, tname); + } + + void LuaState::SetMetatable(const String& tname) const + { + luaL_setmetatable(m_state, tname.GetConstBuffer()); + } + + void LuaState::SetMetatable(int index) const + { + lua_setmetatable(m_state, index); + } + + void LuaState::SetTable(int index) const + { + lua_settable(m_state, index); + } + + void LuaState::SetTableRaw(int index) const + { + lua_rawset(m_state, index); + } + + bool LuaState::ToBoolean(int index) const + { + return lua_toboolean(m_state, index) != 0; + } + + long long LuaState::ToInteger(int index, bool* succeeded) const + { + int success; + long long result = lua_tointegerx(m_state, index, &success); + + if (succeeded) + *succeeded = (success != 0); + + return result; + } + + double LuaState::ToNumber(int index, bool* succeeded) const + { + int success; + double result = lua_tonumberx(m_state, index, &success); + + if (succeeded) + *succeeded = (success != 0); + + return result; + } + + const void* LuaState::ToPointer(int index) const + { + return lua_topointer(m_state, index); + } + + const char* LuaState::ToString(int index, std::size_t* length) const + { + return lua_tolstring(m_state, index, length); + } + + void* LuaState::ToUserdata(int index) const + { + return lua_touserdata(m_state, index); + } + + void* LuaState::ToUserdata(int index, const char* tname) const + { + return luaL_testudata(m_state, index, tname); + } + + void* LuaState::ToUserdata(int index, const String& tname) const + { + return luaL_testudata(m_state, index, tname.GetConstBuffer()); + } + + LuaState& LuaState::operator=(LuaState&& state) noexcept + { + m_lastError = std::move(state.m_lastError); + m_state = state.m_state; + + return *this; + } + + bool LuaState::Run(int argCount, int resultCount) + { + LuaInstance& instance = GetInstance(m_state); + + if (instance.m_level++ == 0) + instance.m_clock.Restart(); + + int status = lua_pcall(m_state, argCount, resultCount, 0); + + instance.m_level--; + + if (status != 0) + { + m_lastError = lua_tostring(m_state, -1); + lua_pop(m_state, 1); + + return false; + } + + return true; + } + + int LuaState::GetIndexOfUpValue(int upValue) + { + return lua_upvalueindex(upValue); + } + + LuaInstance& LuaState::GetInstance(lua_State* internalState) + { + LuaInstance* instance; + lua_getallocf(internalState, reinterpret_cast(&instance)); + + return *instance; + } + + int LuaState::ProxyFunc(lua_State* internalState) + { + LuaFunction& func = *static_cast(lua_touserdata(internalState, lua_upvalueindex(1))); + LuaState state = GetState(internalState); + + return func(state); + } + +} diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index 516364373..3b3d9cb56 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -111,6 +111,52 @@ namespace Nz return SocketImpl::QueryAvailableBytes(m_handle); } + /*! + * \brief Queries the maximum socket receive buffer size + * \return The size of the receive buffer in bytes. + */ + std::size_t AbstractSocket::QueryReceiveBufferSize() const + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket must be created first"); + + return SocketImpl::QueryReceiveBufferSize(m_handle); + } + + /*! + * \brief Queries the maximum socket send buffer size + * \return The size of the send buffer in bytes. + */ + std::size_t AbstractSocket::QuerySendBufferSize() const + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket must be created first"); + + return SocketImpl::QuerySendBufferSize(m_handle); + } + + /*! + * \brief Sets the maximum receive buffer size + * + * \param size The new maximum receive buffer size in bytes + */ + void AbstractSocket::SetReceiveBufferSize(std::size_t size) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket must be created first"); + + SocketImpl::SetReceiveBufferSize(m_handle, size); + } + + /*! + * \brief Sets the maximum send buffer size + * + * \param size The new maximum send buffer size in bytes + */ + void AbstractSocket::SetSendBufferSize(std::size_t size) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket must be created first"); + + SocketImpl::SetSendBufferSize(m_handle, size); + } + /*! * \brief Operation to do when closing socket */ diff --git a/src/Nazara/Network/AlgorithmNetwork.cpp b/src/Nazara/Network/AlgorithmNetwork.cpp index 307ac679a..9a593db39 100644 --- a/src/Nazara/Network/AlgorithmNetwork.cpp +++ b/src/Nazara/Network/AlgorithmNetwork.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -19,7 +19,6 @@ namespace Nz * \param number Optional argument to return the number parsed * \param endOfRead Optional argument to determine where parsing stopped */ - bool ParseDecimal(const char* str, unsigned int* number, const char** endOfRead) { const char* ptr = str; @@ -52,7 +51,6 @@ namespace Nz * \param number Optional argument to return the number parsed * \param endOfRead Optional argument to determine where parsing stopped */ - bool ParseHexadecimal(const char* str, unsigned int* number, const char** endOfRead) { const char* ptr = str; @@ -78,8 +76,113 @@ namespace Nz } } + /*! - * \ingroup network + * \ingroup network + * \brief Returns the text representation of an error + * \return Text representation of an error + * + * \param resolveError Error enumeration + */ + const char* ErrorToString(Nz::ResolveError resolveError) + { + switch (resolveError) + { + case Nz::ResolveError_NoError: + return "No error"; + + case Nz::ResolveError_Internal: + return "An internal error occurred"; + + case Nz::ResolveError_ResourceError: + return "The operating system lacks the resources to proceed"; + + case Nz::ResolveError_NonRecoverable: + return "A nonrecoverable error occurred"; + + case Nz::ResolveError_NotFound: + return "No such host is known"; + + case Nz::ResolveError_NotInitialized: + return "Nazara Network has not been initialized"; + + case Nz::ResolveError_ProtocolNotSupported: + return "A specified protocol is not supported by the server"; + + case Nz::ResolveError_TemporaryFailure: + return "A temporary failure occurred, try again"; + + case Nz::ResolveError_Unknown: + return "An unknown error occurred"; + + default: + return "Invalid error value"; + } + } + + /*! + * \ingroup network + * \brief Returns the text representation of an error + * \return Text representation of an error + * + * \param socketError Error enumeration + */ + const char* ErrorToString(Nz::SocketError socketError) + { + switch (socketError) + { + case Nz::SocketError_NoError: + return "No error"; + + case Nz::SocketError_AddressNotAvailable: + return "The address is already in use"; + + case Nz::SocketError_ConnectionClosed: + return "The connection has been closed"; + + case Nz::SocketError_ConnectionRefused: + return "The connection attempt was refused"; + + case Nz::SocketError_DatagramSize: + return "The datagram size is over the system limit"; + + case Nz::SocketError_Internal: + return "An internal error occurred"; + + case Nz::SocketError_Packet: + return "Packet encoding or decoding failed"; + + case Nz::SocketError_NetworkError: + return "Networking subsystem failed"; + + case Nz::SocketError_NotInitialized: + return "Network module has not been initialized"; + + case Nz::SocketError_NotSupported: + return "This operation is not supported"; + + case Nz::SocketError_ResolveError: + return "The hostname couldn't be resolved"; + + case Nz::SocketError_ResourceError: + return "The operating system lacks the resources to proceed"; + + case Nz::SocketError_TimedOut: + return "The operation timed out"; + + case Nz::SocketError_Unknown: + return "An unknown error occurred"; + + case Nz::SocketError_UnreachableHost: + return "The host is not reachable"; + + default: + return "Invalid error value"; + } + } + + /*! + * \ingroup network * \brief Parse a textual IPv4 or IPv6 address * \return true If successful * @@ -97,7 +200,6 @@ namespace Nz * \remark Produces a NazaraAssert if addressPtr is invalid * \remark Produces a NazaraAssert if result is invalid */ - bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port, bool* isIPv6, const char** endOfRead) { NazaraAssert(addressPtr, "Invalid address string"); diff --git a/src/Nazara/Network/Debug/NewOverload.cpp b/src/Nazara/Network/Debug/NewOverload.cpp index 80be1880c..b6d707ee5 100644 --- a/src/Nazara/Network/Debug/NewOverload.cpp +++ b/src/Nazara/Network/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/ENetHost.cpp b/src/Nazara/Network/ENetHost.cpp new file mode 100644 index 000000000..5850d4ab7 --- /dev/null +++ b/src/Nazara/Network/ENetHost.cpp @@ -0,0 +1,1328 @@ +/* + Copyright(c) 2002 - 2016 Lee Salzman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Copyright (C) 2017 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 + +namespace Nz +{ + namespace + { + static std::size_t s_commandSizes[ENetProtocolCommand_Count] = + { + 0, + sizeof(ENetProtocolAcknowledge), + sizeof(ENetProtocolConnect), + sizeof(ENetProtocolVerifyConnect), + sizeof(ENetProtocolDisconnect), + sizeof(ENetProtocolPing), + sizeof(ENetProtocolSendReliable), + sizeof(ENetProtocolSendUnreliable), + sizeof(ENetProtocolSendFragment), + sizeof(ENetProtocolSendUnsequenced), + sizeof(ENetProtocolBandwidthLimit), + sizeof(ENetProtocolThrottleConfigure), + sizeof(ENetProtocolSendFragment) + }; + } + + + void ENetHost::Broadcast(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet) + { + ENetPacketRef enetPacket = AllocatePacket(flags, std::move(packet)); + + for (ENetPeer& peer : m_peers) + { + if (peer.GetState() != ENetPeerState::Connected) + continue; + + peer.Send(channelId, enetPacket); + } + } + + bool ENetHost::CheckEvents(ENetEvent* event) + { + if (!event) + return false; + + event->type = ENetEventType::None; + event->peer = nullptr; + event->packet.Reset(); + + return DispatchIncomingCommands(event); + } + + ENetPeer* ENetHost::Connect(const IpAddress& remoteAddress, std::size_t channelCount, UInt32 data) + { + NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); + NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); + + std::size_t peerId; + for (peerId = 0; peerId < m_peers.size(); ++peerId) + { + if (m_peers[peerId].GetState() == ENetPeerState::Disconnected) + break; + } + + if (peerId >= m_peers.size()) + { + NazaraError("Insufficient peers"); + return nullptr; + } + + m_channelLimit = Clamp(channelCount, ENetConstants::ENetProtocol_MinimumChannelCount, ENetConstants::ENetProtocol_MaximumChannelCount); + + UInt32 windowSize; + if (m_outgoingBandwidth == 0) + windowSize = ENetProtocol_MaximumWindowSize; + else + windowSize = (m_outgoingBandwidth / ENetConstants::ENetPeer_WindowSizeScale) * ENetProtocol_MinimumWindowSize; + + ENetPeer& peer = m_peers[peerId]; + peer.InitOutgoing(channelCount, remoteAddress, ++m_randomSeed, windowSize); + + ENetProtocol command(ENetProtocolCommand_Connect | ENetProtocolFlag_Acknowledge, 0xFF); + command.connect.channelCount = HostToNet(static_cast(channelCount)); + command.connect.connectID = peer.m_connectID; + command.connect.data = HostToNet(data); + command.connect.incomingBandwidth = HostToNet(m_incomingBandwidth); + command.connect.incomingSessionID = peer.m_incomingSessionID; + command.connect.mtu = HostToNet(peer.m_mtu); + command.connect.outgoingBandwidth = HostToNet(m_outgoingBandwidth); + command.connect.outgoingPeerID = HostToNet(peer.m_incomingPeerID); + command.connect.outgoingSessionID = peer.m_outgoingSessionID; + command.connect.packetThrottleAcceleration = HostToNet(peer.m_packetThrottleAcceleration); + command.connect.packetThrottleDeceleration = HostToNet(peer.m_packetThrottleDeceleration); + command.connect.packetThrottleInterval = HostToNet(peer.m_packetThrottleInterval); + command.connect.windowSize = HostToNet(peer.m_windowSize); + peer.QueueOutgoingCommand(command); + + return &peer; + } + + ENetPeer* ENetHost::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error, std::size_t channelCount, UInt32 data) + { + std::vector results = IpAddress::ResolveHostname(protocol, hostName, service, error); + if (results.empty()) + return nullptr; + + 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, channelCount, data); + } + + bool ENetHost::Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount) + { + return Create(address, peerCount, channelCount, 0, 0); + } + + bool ENetHost::Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth) + { + NazaraAssert(address.IsValid(), "Invalid listening address"); + + if (peerCount > ENetConstants::ENetProtocol_MaximumPeerId) + { + NazaraError("Peer count exceeds maximum peer count supported by protocol (" + String::Number(ENetConstants::ENetProtocol_MaximumPeerId) + ")"); + return false; + } + + if (!InitSocket(address)) + return false; + + m_address = address; + m_randomSeed = *reinterpret_cast(this); + m_randomSeed += s_randomGenerator(); + m_randomSeed = (m_randomSeed << 16) | (m_randomSeed >> 16); + m_channelLimit = Clamp(channelCount, ENetConstants::ENetProtocol_MinimumChannelCount, ENetConstants::ENetProtocol_MaximumChannelCount); + m_incomingBandwidth = incomingBandwidth; + m_outgoingBandwidth = outgoingBandwidth; + m_bandwidthThrottleEpoch = 0; + m_recalculateBandwidthLimits = false; + m_mtu = ENetConstants::ENetHost_DefaultMTU; + m_commandCount = 0; + m_bufferCount = 0; + m_peerCount = peerCount; + m_receivedAddress = IpAddress::AnyIpV4; + m_receivedData = nullptr; + m_receivedDataLength = 0; + + m_totalSentData = 0; + m_totalSentPackets = 0; + m_totalReceivedData = 0; + m_totalReceivedPackets = 0; + + m_bandwidthLimitedPeers = 0; + m_connectedPeers = 0; + m_duplicatePeers = ENetConstants::ENetProtocol_MaximumPeerId; + m_maximumPacketSize = ENetConstants::ENetHost_DefaultMaximumPacketSize; + m_maximumWaitingData = ENetConstants::ENetHost_DefaultMaximumWaitingData; + + m_peers.reserve(peerCount); + for (std::size_t i = 0; i < peerCount; ++i) + m_peers.emplace_back(this, UInt16(i)); + + return true; + } + + void ENetHost::Flush() + { + m_serviceTime = GetElapsedMilliseconds(); + + SendOutgoingCommands(nullptr, 0); + } + + int ENetHost::Service(ENetEvent* event, UInt32 timeout) + { + if (event) + { + event->type = ENetEventType::None; + event->peer = nullptr; + event->packet = nullptr; + + if (DispatchIncomingCommands(event)) + return 1; + } + + m_serviceTime = GetElapsedMilliseconds(); + timeout += m_serviceTime; + + do + { + if (ENetTimeDifference(m_serviceTime, m_bandwidthThrottleEpoch) >= ENetConstants::ENetHost_BandwidthThrottleInterval) + ThrottleBandwidth(); + + switch (SendOutgoingCommands(event, true)) + { + case 1: + return 1; + + case -1: + NazaraError("Error sending outgoing packets"); + return -1; + + default: + break; + } + + switch (ReceiveIncomingCommands(event)) + { + case 1: + return 1; + + case -1: + NazaraError("Error receiving incoming packets"); + return -1; + + default: + break; + } + + switch (SendOutgoingCommands(event, true)) + { + case 1: + return 1; + + case -1: + NazaraError("Error sending outgoing packets"); + + return -1; + + default: + break; + } + + if (event) + { + if (DispatchIncomingCommands(event)) + return 1; + } + + if (ENetTimeGreaterEqual(m_serviceTime, timeout)) + return 0; + + for (;;) + { + m_serviceTime = GetElapsedMilliseconds(); + + if (ENetTimeGreaterEqual(m_serviceTime, timeout)) + return 0; + + if (m_poller.Wait(ENetTimeDifference(timeout, m_serviceTime))) + break; + } + + m_serviceTime = GetElapsedMilliseconds(); + } + while (m_poller.IsReadyToRead(m_socket)); + + return 0; + } + + void ENetHost::SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay) + { + NazaraAssert(maxDelay >= minDelay, "Maximum delay cannot be greater than minimum delay"); + + if (packetLossProbability <= 0.0 && minDelay == 0 && maxDelay == 0) + m_isSimulationEnabled = false; + else + { + m_isSimulationEnabled = true; + m_packetDelayDistribution = std::uniform_int_distribution(minDelay, maxDelay); + m_packetLossProbability = std::bernoulli_distribution(packetLossProbability); + } + } + + ENetPacketRef ENetHost::AllocatePacket(ENetPacketFlags flags) + { + ENetPacketRef enetPacket = m_packetPool.New(); + enetPacket->flags = flags; + enetPacket->owner = &m_packetPool; + + return enetPacket; + } + + bool ENetHost::InitSocket(const IpAddress& address) + { + if (!m_socket.Create(address.GetProtocol())) + return false; + + m_socket.EnableBlocking(false); + m_socket.EnableBroadcasting(true); + m_socket.SetReceiveBufferSize(ENetConstants::ENetHost_ReceiveBufferSize); + m_socket.SetSendBufferSize(ENetConstants::ENetHost_SendBufferSize); + + if (!address.IsLoopback()) + { + if (m_socket.Bind(address) != SocketState_Bound) + { + NazaraError("Failed to bind address " + address.ToString()); + return false; + } + } + + m_poller.RegisterSocket(m_socket, SocketPollEvent_Read); + + return true; + } + + void ENetHost::AddToDispatchQueue(ENetPeer* peer) + { + m_dispatchQueue.UnboundedSet(peer->GetPeerId()); + } + + void ENetHost::RemoveFromDispatchQueue(ENetPeer* peer) + { + m_dispatchQueue.UnboundedReset(peer->GetPeerId()); + } + + bool ENetHost::DispatchIncomingCommands(ENetEvent* event) + { + for (std::size_t bit = m_dispatchQueue.FindFirst(); bit != m_dispatchQueue.npos; bit = m_dispatchQueue.FindNext(bit)) + { + m_dispatchQueue.Reset(bit); + + ENetPeer& peer = m_peers[bit]; + switch (peer.GetState()) + { + case ENetPeerState::ConnectionPending: + peer.ChangeState(ENetPeerState::Connected); + + event->type = ENetEventType::IncomingConnect; + event->peer = &peer; + event->data = peer.m_eventData; + return true; + + case ENetPeerState::ConnectionSucceeded: + peer.ChangeState(ENetPeerState::Connected); + + event->type = ENetEventType::OutgoingConnect; + event->peer = &peer; + event->data = peer.m_eventData; + return true; + + case ENetPeerState::Zombie: + m_recalculateBandwidthLimits = true; + + event->type = ENetEventType::Disconnect; + event->peer = &peer; + event->data = peer.m_eventData; + + peer.Reset(); + return true; + + case ENetPeerState::Connected: + if (peer.m_dispatchedCommands.empty()) + continue; + + if (!peer.Receive(&event->packet, &event->channelId)) + continue; + + event->type = ENetEventType::Receive; + event->peer = &peer; + + if (!peer.m_dispatchedCommands.empty()) + AddToDispatchQueue(&peer); + + return true; + + default: + break; + } + } + + return false; + } + + ENetPeer* ENetHost::HandleConnect(ENetProtocolHeader* /*header*/, ENetProtocol* command) + { + UInt32 channelCount = NetToHost(command->connect.channelCount); + + if (channelCount < ENetProtocol_MinimumChannelCount || channelCount > ENetProtocol_MaximumChannelCount) + return nullptr; + + std::size_t duplicatePeers = 0; + ENetPeer* peer = nullptr; + for (ENetPeer& currentPeer : m_peers) + { + if (currentPeer.GetState() == ENetPeerState::Disconnected) + { + if (!peer) + peer = ¤tPeer; + } + else if (currentPeer.GetState() != ENetPeerState::Connecting) + { + // Compare users without comparing their port + IpAddress first(currentPeer.m_address); + first.SetPort(0); + + IpAddress second(m_receivedAddress); + second.SetPort(0); + + if (first == second) + { + if (currentPeer.m_address.GetPort() == m_receivedAddress.GetPort() && currentPeer.m_connectID == command->connect.connectID) + return nullptr; + + ++duplicatePeers; + } + } + } + + if (!peer || duplicatePeers >= m_duplicatePeers) + return nullptr; + + channelCount = std::min(channelCount, UInt32(m_channelLimit)); + + peer->InitIncoming(channelCount, m_receivedAddress, command->connect); + + UInt32 windowSize; + if (m_incomingBandwidth == 0) + windowSize = ENetConstants::ENetProtocol_MaximumWindowSize; + else + windowSize = (m_incomingBandwidth / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize; + + windowSize = std::max(windowSize, NetToHost(command->connect.windowSize)); + windowSize = Clamp(windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize); + + ENetProtocol verifyCommand(ENetProtocolCommand_VerifyConnect | ENetProtocolFlag_Acknowledge, 0xFF); + verifyCommand.verifyConnect.connectID = peer->m_connectID; + verifyCommand.verifyConnect.incomingSessionID = peer->m_outgoingSessionID; + verifyCommand.verifyConnect.outgoingSessionID = peer->m_incomingSessionID; + + verifyCommand.verifyConnect.channelCount = HostToNet(channelCount); + verifyCommand.verifyConnect.incomingBandwidth = HostToNet(m_incomingBandwidth); + verifyCommand.verifyConnect.mtu = HostToNet(peer->GetMtu()); + verifyCommand.verifyConnect.outgoingBandwidth = HostToNet(m_outgoingBandwidth); + verifyCommand.verifyConnect.outgoingPeerID = HostToNet(peer->GetPeerId()); + verifyCommand.verifyConnect.packetThrottleAcceleration = HostToNet(peer->GetPacketThrottleAcceleration()); + verifyCommand.verifyConnect.packetThrottleDeceleration = HostToNet(peer->GetPacketThrottleDeceleration()); + verifyCommand.verifyConnect.packetThrottleInterval = HostToNet(peer->GetPacketThrottleInterval()); + verifyCommand.verifyConnect.windowSize = HostToNet(windowSize); + + peer->QueueOutgoingCommand(verifyCommand); + + return peer; + } + + bool ENetHost::HandleIncomingCommands(ENetEvent* event) + { + if (m_receivedDataLength < NazaraOffsetOf(ENetProtocolHeader, sentTime)) + return false; + + ENetProtocolHeader* header = reinterpret_cast(m_receivedData); + + UInt16 peerID = NetToHost(header->peerID); + UInt8 sessionID = (peerID & ENetProtocolHeaderSessionMask) >> ENetProtocolHeaderSessionShift; + UInt16 flags = peerID & ENetProtocolHeaderFlag_Mask; + peerID &= ~(ENetProtocolHeaderFlag_Mask | ENetProtocolHeaderSessionMask); + + std::size_t headerSize = (flags & ENetProtocolHeaderFlag_SentTime) ? sizeof(ENetProtocolHeader) : NazaraOffsetOf(ENetProtocolHeader, sentTime); + + ENetPeer* peer; + if (peerID == ENetConstants::ENetProtocol_MaximumPeerId) + peer = nullptr; + else + { + if (peerID >= m_peers.size()) + return false; + else + { + peer = &m_peers[peerID]; + + if (peer->GetState() == ENetPeerState::Disconnected || peer->GetState() == ENetPeerState::Zombie) + return false; + + if (m_receivedAddress != peer->GetAddress() && peer->GetAddress() != IpAddress::BroadcastIpV4) + return false; + + if (peer->m_outgoingPeerID < ENetConstants::ENetProtocol_MaximumPeerId && sessionID != peer->m_incomingSessionID) + return false; + } + } + + // Compression handling + + // Checksum + + if (peer) + { + peer->m_address = m_receivedAddress; + peer->m_incomingDataTotal += UInt32(m_receivedDataLength); + } + + auto commandError = [&]() -> bool + { + if (event && event->type != ENetEventType::None) + return true; + + return false; + }; + + UInt8* currentData = m_receivedData + headerSize; + + while (currentData < &m_receivedData[m_receivedDataLength]) + { + ENetProtocol* command = reinterpret_cast(currentData); + + if (currentData + sizeof(ENetProtocolCommandHeader) > &m_receivedData[m_receivedDataLength]) + break; + + UInt8 commandNumber = command->header.command & ENetProtocolCommand_Mask; + if (commandNumber >= ENetProtocolCommand_Count) + break; + + std::size_t commandSize = s_commandSizes[commandNumber]; + if (commandSize == 0 || currentData + commandSize > &m_receivedData[m_receivedDataLength]) + break; + + currentData += commandSize; + + if (!peer && commandNumber != ENetProtocolCommand_Connect) + break; + + command->header.reliableSequenceNumber = NetToHost(command->header.reliableSequenceNumber); + + switch (commandNumber) + { + case ENetProtocolCommand_Acknowledge: + if (!peer->HandleAcknowledge(command, event)) + return commandError(); + + break; + + case ENetProtocolCommand_Connect: + if (peer) + return commandError(); + + peer = HandleConnect(header, command); + if (!peer) + return commandError(); + + break; + + case ENetProtocolCommand_VerifyConnect: + if (!peer->HandleVerifyConnect(command, event)) + return commandError(); + + break; + + case ENetProtocolCommand_Disconnect: + if (!peer->HandleDisconnect(command)) + return commandError(); + + break; + + case ENetProtocolCommand_Ping: + if (!peer->HandlePing(command)) + return commandError(); + + break; + + case ENetProtocolCommand_SendReliable: + if (!peer->HandleSendReliable(command, ¤tData)) + return commandError(); + + break; + + case ENetProtocolCommand_SendUnreliable: + if (!peer->HandleSendUnreliable(command, ¤tData)) + return commandError(); + + break; + + case ENetProtocolCommand_SendUnsequenced: + if (!peer->HandleSendUnsequenced(command, ¤tData)) + return commandError(); + + break; + + case ENetProtocolCommand_SendFragment: + if (!peer->HandleSendFragment(command, ¤tData)) + return commandError(); + + break; + + case ENetProtocolCommand_BandwidthLimit: + if (!peer->HandleBandwidthLimit(command)) + return commandError(); + + break; + + case ENetProtocolCommand_ThrottleConfigure: + if (!peer->HandleThrottleConfigure(command)) + return commandError(); + + break; + + case ENetProtocolCommand_SendUnreliableFragment: + if (!peer->HandleSendUnreliableFragment(command, ¤tData)) + return commandError(); + + break; + + default: + return commandError(); + } + + if (peer && (command->header.command & ENetProtocolFlag_Acknowledge) != 0) + { + UInt16 sentTime; + + if (!(flags & ENetProtocolHeaderFlag_SentTime)) + break; + + sentTime = NetToHost(header->sentTime); + + switch (peer->GetState()) + { + case ENetPeerState::Disconnecting: + case ENetPeerState::AcknowledgingConnect: + case ENetPeerState::Disconnected: + case ENetPeerState::Zombie: + break; + + case ENetPeerState::AcknowledgingDisconnect: + if ((command->header.command & ENetProtocolCommand_Mask) == ENetProtocolCommand_Disconnect) + peer->QueueAcknowledgement(command, sentTime); + break; + + default: + peer->QueueAcknowledgement(command, sentTime); + break; + } + } + } + + return commandError(); + } + + int ENetHost::ReceiveIncomingCommands(ENetEvent* event) + { + for (unsigned int i = 0; i < 256; ++i) + { + bool shouldReceive = true; + std::size_t receivedLength; + + if (m_isSimulationEnabled) + { + for (auto it = m_pendingIncomingPackets.begin(); it != m_pendingIncomingPackets.end(); ++it) + { + if (m_serviceTime >= it->deliveryTime) + { + shouldReceive = false; + + m_receivedAddress = it->from; + receivedLength = it->data.GetDataSize(); + std::memcpy(m_packetData[0].data(), it->data.GetConstData() + NetPacket::HeaderSize, receivedLength); + + m_pendingIncomingPackets.erase(it); + break; + } + } + } + + if (shouldReceive) + { + if (!m_socket.Receive(m_packetData[0].data(), m_packetData[0].size(), &m_receivedAddress, &receivedLength)) + return -1; //< Error + + if (receivedLength == 0) + return 0; + + if (m_isSimulationEnabled) + { + if (m_packetLossProbability(s_randomGenerator)) + continue; + + UInt16 delay = m_packetDelayDistribution(s_randomGenerator); + if (delay > 0) + { + PendingIncomingPacket pendingPacket; + pendingPacket.deliveryTime = m_serviceTime + delay; + pendingPacket.from = m_receivedAddress; + pendingPacket.data.Reset(0, m_packetData[0].data(), receivedLength); + + auto it = std::upper_bound(m_pendingIncomingPackets.begin(), m_pendingIncomingPackets.end(), pendingPacket, [] (const PendingIncomingPacket& first, const PendingIncomingPacket& second) + { + return first.deliveryTime < second.deliveryTime; + }); + + m_pendingIncomingPackets.emplace(it, std::move(pendingPacket)); + continue; + } + } + } + + m_receivedData = m_packetData[0].data(); + m_receivedDataLength = receivedLength; + + m_totalReceivedData += receivedLength; + m_totalReceivedPackets++; + + // Intercept + + if (HandleIncomingCommands(event)) + return 1; + } + + return -1; + } + + void ENetHost::NotifyConnect(ENetPeer* peer, ENetEvent* event, bool incoming) + { + m_recalculateBandwidthLimits = true; + + if (event) + { + peer->ChangeState(ENetPeerState::Connected); + + event->type = (incoming) ? ENetEventType::IncomingConnect : ENetEventType::OutgoingConnect; + event->peer = peer; + event->data = peer->m_eventData; + } + else + peer->DispatchState((peer->GetState() == ENetPeerState::Connecting) ? ENetPeerState::ConnectionSucceeded : ENetPeerState::ConnectionPending); + } + + void ENetHost::NotifyDisconnect(ENetPeer* peer, ENetEvent* event) + { + if (peer->GetState() >= ENetPeerState::ConnectionPending) + m_recalculateBandwidthLimits = true; + + if (peer->GetState() != ENetPeerState::Connecting && (peer->GetState() < ENetPeerState::ConnectionSucceeded)) + peer->Reset(); + else if (event) + { + event->type = ENetEventType::Disconnect; + event->peer = peer; + event->data = peer->m_eventData; + + peer->Reset(); + } + else + { + peer->m_eventData = 0; + + peer->DispatchState(ENetPeerState::Zombie); + } + } + + void ENetHost::SendAcknowledgements(ENetPeer* peer) + { + auto it = peer->m_acknowledgements.begin(); + for (; it != peer->m_acknowledgements.end(); ++it) + { + if (m_commandCount >= m_commands.size() || m_bufferCount >= m_buffers.size() || peer->GetMtu() - m_packetSize < sizeof(ENetProtocolAcknowledge)) + { + m_continueSending = true; + break; + } + + ENetPeer::Acknowledgement& acknowledgement = *it; + + ENetProtocol& command = m_commands[m_commandCount]; + NetBuffer& buffer = m_buffers[m_bufferCount]; + + buffer.data = &command; + buffer.dataLength = sizeof(ENetProtocolAcknowledge); + + m_packetSize += buffer.dataLength; + + UInt16 reliableSequenceNumber = HostToNet(acknowledgement.command.header.reliableSequenceNumber); + + command.header.command = ENetProtocolCommand_Acknowledge; + command.header.channelID = acknowledgement.command.header.channelID; + command.header.reliableSequenceNumber = reliableSequenceNumber; + command.acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; + command.acknowledge.receivedSentTime = HostToNet(acknowledgement.sentTime); + + if ((acknowledgement.command.header.command & ENetProtocolCommand_Mask) == ENetProtocolCommand_Disconnect) + peer->DispatchState(ENetPeerState::Zombie); + + ++m_bufferCount; + ++m_commandCount; + } + + peer->m_acknowledgements.erase(peer->m_acknowledgements.begin(), it); + } + + bool ENetHost::SendReliableOutgoingCommands(ENetPeer* peer) + { + bool canPing = true; + bool windowExceeded = false; + bool windowWrap = false; + + auto currentCommand = peer->m_outgoingReliableCommands.begin(); + while (currentCommand != peer->m_outgoingReliableCommands.end()) + { + auto outgoingCommand = currentCommand; + + UInt16 reliableWindow = outgoingCommand->reliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + ENetPeer::Channel* channel = (outgoingCommand->command.header.channelID < peer->m_channels.size()) ? &peer->m_channels[outgoingCommand->command.header.channelID] : nullptr; + if (channel) + { + if (!windowWrap && outgoingCommand->sendAttempts < 1 && !(outgoingCommand->reliableSequenceNumber % ENetPeer_ReliableWindowSize) && + ((channel->reliableWindows[(reliableWindow + ENetPeer_ReliableWindows - 1) % ENetPeer_ReliableWindows] >= ENetPeer_ReliableWindowSize) || + channel->usedReliableWindows & ((((1 << ENetPeer_ReliableWindows) - 1) << reliableWindow) | + (((1 << ENetPeer_FreeReliableWindows) - 1) >> (ENetPeer_ReliableWindows - reliableWindow))))) + windowWrap = true; + + if (windowWrap) + { + ++currentCommand; + continue; + } + } + + if (outgoingCommand->packet) + { + if (!windowExceeded) + { + UInt32 windowSize = (peer->m_packetThrottle * peer->m_windowSize) / ENetPeer_PacketThrottleScale; + + if (peer->m_reliableDataInTransit + outgoingCommand->fragmentLength > std::max(windowSize, peer->GetMtu())) + windowExceeded = true; + } + + if (windowExceeded) + { + ++currentCommand; + continue; + } + } + + canPing = false; + + std::size_t commandSize = s_commandSizes[outgoingCommand->command.header.command & ENetProtocolCommand_Mask]; + if (m_commandCount >= m_commands.size() || m_bufferCount + 1 >= m_buffers.size() || peer->GetMtu() - m_packetSize < commandSize || + (outgoingCommand->packet && UInt16(peer->GetMtu() - m_packetSize) < UInt16(commandSize + outgoingCommand->fragmentLength))) + { + m_continueSending = true; + break; + } + + ++currentCommand; + + if (channel && outgoingCommand->sendAttempts < 1) + { + channel->usedReliableWindows |= 1 << reliableWindow; + ++channel->reliableWindows[reliableWindow]; + } + + ++outgoingCommand->sendAttempts; + + if (outgoingCommand->roundTripTimeout == 0) + { + outgoingCommand->roundTripTimeout = peer->m_roundTripTime + 4 * peer->m_roundTripTimeVariance; + outgoingCommand->roundTripTimeoutLimit = peer->m_timeoutLimit * outgoingCommand->roundTripTimeout; + } + + if (peer->m_sentReliableCommands.empty()) + peer->m_nextTimeout = m_serviceTime + outgoingCommand->roundTripTimeout; + + peer->m_sentReliableCommands.emplace_back(std::move(*outgoingCommand)); + peer->m_outgoingReliableCommands.erase(outgoingCommand); + + outgoingCommand = peer->m_sentReliableCommands.end(); + --outgoingCommand; + + outgoingCommand->sentTime = m_serviceTime; + + ENetProtocol& command = m_commands[m_commandCount]; + NetBuffer& buffer = m_buffers[m_bufferCount]; + + buffer.data = &command; + buffer.dataLength = commandSize; + + m_packetSize += buffer.dataLength; + m_headerFlags |= ENetProtocolHeaderFlag_SentTime; + + command = outgoingCommand->command; + + if (outgoingCommand->packet) + { + ++m_bufferCount; + + NetBuffer& packetBuffer = m_buffers[m_bufferCount]; + packetBuffer.data = outgoingCommand->packet->data.GetData() + Nz::NetPacket::HeaderSize + outgoingCommand->fragmentOffset; + packetBuffer.dataLength = outgoingCommand->fragmentLength; + + m_packetSize += packetBuffer.dataLength; + + peer->m_reliableDataInTransit += outgoingCommand->fragmentLength; + } + + ++peer->m_packetsSent; + ++peer->m_totalPacketSent; + ++m_bufferCount; + ++m_commandCount; + } + + return canPing; + } + + int ENetHost::SendOutgoingCommands(ENetEvent* event, bool checkForTimeouts) + { + std::array headerData; + ENetProtocolHeader* header = reinterpret_cast(headerData.data()); + + m_continueSending = true; + + while (m_continueSending) + { + m_continueSending = false; + + for (std::size_t peer = 0; peer < m_peerCount; ++peer) + { + ENetPeer* currentPeer = &m_peers[peer]; + if (currentPeer->GetState() == ENetPeerState::Disconnected || currentPeer->GetState() == ENetPeerState::Zombie) + continue; + + m_headerFlags = 0; + m_commandCount = 0; + m_bufferCount = 1; + m_packetSize = sizeof(ENetProtocolHeader); + + if (!currentPeer->m_acknowledgements.empty()) + SendAcknowledgements(currentPeer); + + if (checkForTimeouts && !currentPeer->m_sentReliableCommands.empty() && ENetTimeGreaterEqual(m_serviceTime, currentPeer->m_nextTimeout) && currentPeer->CheckTimeouts(event)) + { + if (event && event->type != ENetEventType::None) + return 1; + else + continue; + } + + if ((currentPeer->m_outgoingReliableCommands.empty() || SendReliableOutgoingCommands(currentPeer)) && currentPeer->m_sentReliableCommands.empty() && + ENetTimeDifference(m_serviceTime, currentPeer->m_lastReceiveTime) >= currentPeer->m_pingInterval && currentPeer->m_mtu - m_packetSize >= sizeof(ENetProtocolPing)) + { + currentPeer->Ping(); + SendReliableOutgoingCommands(currentPeer); + } + + if (!currentPeer->m_outgoingUnreliableCommands.empty()) + SendUnreliableOutgoingCommands(currentPeer); + + if (m_commandCount == 0) + continue; + + if (currentPeer->m_packetLossEpoch == 0) + currentPeer->m_packetLossEpoch = m_serviceTime; + else if (ENetTimeDifference(m_serviceTime, currentPeer->m_packetLossEpoch) >= ENetPeer_PacketLossInterval && currentPeer->m_packetsSent > 0) + { + UInt32 packetLoss = currentPeer->m_packetsLost * ENetPeer_PacketLossScale / currentPeer->m_packetsSent; + + #ifdef ENET_DEBUG + printf("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer->incomingPeerID, currentPeer->packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer->packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer->roundTripTime, currentPeer->roundTripTimeVariance, currentPeer->packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size(¤tPeer->outgoingReliableCommands), enet_list_size(¤tPeer->outgoingUnreliableCommands), currentPeer->channels != NULL ? enet_list_size(¤tPeer->channels->incomingReliableCommands) : 0, currentPeer->channels != NULL ? enet_list_size(¤tPeer->channels->incomingUnreliableCommands) : 0); + #endif + + currentPeer->m_packetLossVariance -= currentPeer->m_packetLossVariance / 4; + + if (packetLoss >= currentPeer->m_packetLoss) + { + currentPeer->m_packetLoss += (packetLoss - currentPeer->m_packetLoss) / 8; + currentPeer->m_packetLossVariance += (packetLoss - currentPeer->m_packetLoss) / 4; + } + else + { + currentPeer->m_packetLoss -= (currentPeer->m_packetLoss - packetLoss) / 8; + currentPeer->m_packetLossVariance += (currentPeer->m_packetLoss - packetLoss) / 4; + } + + currentPeer->m_packetLossEpoch = m_serviceTime; + currentPeer->m_packetsSent = 0; + currentPeer->m_packetsLost = 0; + } + + + m_buffers[0].data = headerData.data(); + if (m_headerFlags & ENetProtocolHeaderFlag_SentTime) + { + header->sentTime = HostToNet(static_cast(m_serviceTime)); + + m_buffers[0].dataLength = sizeof(ENetProtocolHeader); + } + else + m_buffers[0].dataLength = NazaraOffsetOf(ENetProtocolHeader, sentTime); + + if (currentPeer->m_outgoingPeerID < ENetConstants::ENetProtocol_MaximumPeerId) + m_headerFlags |= currentPeer->m_outgoingSessionID << ENetProtocolHeaderSessionShift; + + header->peerID = HostToNet(static_cast(currentPeer->m_outgoingPeerID | m_headerFlags)); + + currentPeer->m_lastSendTime = m_serviceTime; + + // Simulate network by adding delay to packet sending and losing some packets + bool sendNow = true; + if (currentPeer->IsSimulationEnabled()) + { + sendNow = false; + if (!currentPeer->m_packetLossProbability(s_randomGenerator)) + { + Nz::UInt16 delay = currentPeer->m_packetDelayDistribution(s_randomGenerator); + if (delay == 0) + sendNow = true; + else + { + PendingOutgoingPacket outgoingPacket; + outgoingPacket.deliveryTime = m_serviceTime + delay; + outgoingPacket.to = currentPeer->GetAddress(); + + // Accumulate every temporary buffer into a datagram + for (std::size_t i = 0; i < m_bufferCount; ++i) + { + NetBuffer& buffer = m_buffers[i]; + outgoingPacket.data.Write(buffer.data, buffer.dataLength); + } + + m_totalSentData += outgoingPacket.data.GetDataSize(); + + // Add it to the right place + auto it = std::upper_bound(m_pendingOutgoingPackets.begin(), m_pendingOutgoingPackets.end(), outgoingPacket, [](const PendingOutgoingPacket& first, const PendingOutgoingPacket& second) + { + return first.deliveryTime < second.deliveryTime; + }); + + m_pendingOutgoingPackets.emplace(it, std::move(outgoingPacket)); + } + } + } + + if (sendNow) + { + std::size_t sentLength = 0; + + if (!m_socket.SendMultiple(currentPeer->GetAddress(), m_buffers.data(), m_bufferCount, &sentLength)) + return -1; + + m_totalSentData += sentLength; + } + + currentPeer->RemoveSentUnreliableCommands(); + m_totalSentPackets++; + } + } + + if (!m_pendingOutgoingPackets.empty()) + { + auto it = m_pendingOutgoingPackets.begin(); + for (; it != m_pendingOutgoingPackets.end(); ++it) + { + if (m_serviceTime < it->deliveryTime) + break; + + if (!m_socket.Send(it->to, it->data.GetConstData() + NetPacket::HeaderSize, it->data.GetDataSize(), nullptr)) + return -1; + } + + m_pendingOutgoingPackets.erase(m_pendingOutgoingPackets.begin(), it); + } + + return 0; + } + + void ENetHost::SendUnreliableOutgoingCommands(ENetPeer* peer) + { + auto currentCommand = peer->m_outgoingUnreliableCommands.begin(); + while (currentCommand != peer->m_outgoingUnreliableCommands.end()) + { + auto outgoingCommand = currentCommand; + + std::size_t commandSize = s_commandSizes[outgoingCommand->command.header.command & ENetProtocolCommand_Mask]; + + if (m_commandCount >= m_commands.size() || m_bufferCount + 1 >= m_buffers.size() || peer->m_mtu - m_packetSize < commandSize || + (outgoingCommand->packet && peer->m_mtu - m_packetSize < commandSize + outgoingCommand->fragmentLength)) + { + m_continueSending = true; + break; + } + + ++currentCommand; + + if (outgoingCommand->packet && outgoingCommand->fragmentOffset == 0) + { + peer->m_packetThrottleCounter += ENetConstants::ENetPeer_PacketThrottleCounter; + peer->m_packetThrottleCounter %= ENetConstants::ENetPeer_PacketThrottleScale; + + if (peer->m_packetThrottleCounter > peer->m_packetThrottle) + { + UInt16 reliableSequenceNumber = outgoingCommand->reliableSequenceNumber; + UInt16 unreliableSequenceNumber = outgoingCommand->unreliableSequenceNumber; + + for (;;) + { + peer->m_outgoingUnreliableCommands.erase(outgoingCommand); + + if (currentCommand == peer->m_outgoingUnreliableCommands.end()) + break; + + outgoingCommand = currentCommand; + if (outgoingCommand->reliableSequenceNumber != reliableSequenceNumber || outgoingCommand->unreliableSequenceNumber != unreliableSequenceNumber) + break; + + ++currentCommand; + } + + continue; + } + } + + ENetProtocol& command = m_commands[m_commandCount]; + NetBuffer& buffer = m_buffers[m_bufferCount]; + + buffer.data = &command; + buffer.dataLength = commandSize; + + command = outgoingCommand->command; + + if (outgoingCommand->packet) + { + ++m_bufferCount; + + NetBuffer& packetBuffer = m_buffers[m_bufferCount]; + packetBuffer.data = outgoingCommand->packet->data.GetData() + Nz::NetPacket::HeaderSize + outgoingCommand->fragmentOffset; + packetBuffer.dataLength = outgoingCommand->fragmentLength; + + m_packetSize += packetBuffer.dataLength; + + // In order to keep the packet buffer alive until we send it, place it into a temporary queue + peer->m_sentUnreliableCommands.emplace_back(std::move(*outgoingCommand)); + } + + peer->m_outgoingUnreliableCommands.erase(outgoingCommand); + + ++m_bufferCount; + ++m_commandCount; + } + + if (peer->GetState() == ENetPeerState::DisconnectLater && !peer->HasPendingCommands()) + peer->Disconnect(peer->m_eventData); + } + + void ENetHost::ThrottleBandwidth() + { + UInt32 currentTime = GetElapsedMilliseconds(); + UInt32 elapsedTime = currentTime - m_bandwidthThrottleEpoch; + + if (elapsedTime < ENetConstants::ENetHost_BandwidthThrottleInterval) + return; + + m_bandwidthThrottleEpoch = currentTime; + + if (m_connectedPeers == 0) + return; + + UInt32 dataTotal = ~0; + UInt32 bandwidth = ~0; + + if (m_outgoingBandwidth != 0) + { + bandwidth = (m_outgoingBandwidth * elapsedTime) / 1000; + + dataTotal = 0; + for (ENetPeer& peer : m_peers) + { + if (peer.IsConnected()) + continue; + + dataTotal += peer.m_outgoingDataTotal; + } + } + + UInt32 peersRemaining = m_connectedPeers; + UInt32 bandwidthLimit = ~0; + UInt32 throttle = ~0; + bool needsAdjustment = m_bandwidthLimitedPeers > 0; + + while (peersRemaining > 0 && needsAdjustment) + { + needsAdjustment = false; + + if (dataTotal <= bandwidth) + throttle = ENetConstants::ENetPeer_PacketThrottleScale; + else + throttle = (bandwidth * ENetConstants::ENetPeer_PacketThrottleScale) / dataTotal; + + for (ENetPeer& peer : m_peers) + { + if (!peer.IsConnected() || peer.m_incomingBandwidth == 0 || peer.m_outgoingBandwidthThrottleEpoch == currentTime) + continue; + + UInt32 peerBandwidth = (peer.m_incomingBandwidth * elapsedTime) / 1000; + if ((throttle * peer.m_outgoingDataTotal) / ENetConstants::ENetPeer_PacketThrottleScale <= peerBandwidth) + continue; + + peer.m_packetThrottleLimit = Clamp((peerBandwidth * ENetConstants::ENetPeer_PacketThrottleScale) / peer.m_outgoingDataTotal, 0, peer.m_packetThrottleLimit); + peer.m_outgoingBandwidthThrottleEpoch = currentTime; + + peer.m_incomingDataTotal = 0; + peer.m_outgoingDataTotal = 0; + + needsAdjustment = true; + --peersRemaining; + bandwidth -= peerBandwidth; + dataTotal -= peerBandwidth; + } + } + + if (peersRemaining > 0) + { + if (dataTotal <= bandwidth) + throttle = ENetConstants::ENetPeer_PacketThrottleScale; + else + throttle = (bandwidth * ENetConstants::ENetPeer_PacketThrottleScale) / dataTotal; + + for (ENetPeer& peer : m_peers) + { + if (!peer.IsConnected() || peer.m_outgoingBandwidthThrottleEpoch == currentTime) + continue; + + peer.m_packetThrottleLimit = throttle; + peer.m_packetThrottle = std::min(peer.m_packetThrottle, peer.m_packetThrottleLimit); + + peer.m_incomingDataTotal = 0; + peer.m_outgoingDataTotal = 0; + } + } + + if (m_recalculateBandwidthLimits) + { + m_recalculateBandwidthLimits = false; + + peersRemaining = m_connectedPeers; + bandwidth = m_incomingBandwidth; + needsAdjustment = true; + + if (bandwidth == 0) + bandwidthLimit = 0; + else + { + while (peersRemaining > 0 && needsAdjustment) + { + needsAdjustment = false; + bandwidthLimit = bandwidth / peersRemaining; + + for (ENetPeer& peer : m_peers) + { + if (!peer.IsConnected() || peer.m_incomingBandwidthThrottleEpoch == currentTime) + continue; + + if (peer.m_outgoingBandwidth > 0 && peer.m_outgoingBandwidth >= bandwidthLimit) + continue; + + peer.m_incomingBandwidthThrottleEpoch = currentTime; + + needsAdjustment = true; + --peersRemaining; + bandwidth -= peer.m_outgoingBandwidth; + } + } + } + + for (ENetPeer& peer : m_peers) + { + if (!peer.IsConnected()) + continue; + + ENetProtocol command(ENetProtocolCommand_BandwidthLimit | ENetProtocolFlag_Acknowledge, 0xFF); + command.bandwidthLimit.outgoingBandwidth = HostToNet(m_outgoingBandwidth); + + if (peer.m_incomingBandwidthThrottleEpoch == currentTime) + command.bandwidthLimit.incomingBandwidth = HostToNet(peer.m_outgoingBandwidth); + else + command.bandwidthLimit.incomingBandwidth = HostToNet(bandwidthLimit); + + peer.QueueOutgoingCommand(command); + } + } + } + + std::size_t ENetHost::GetCommandSize(UInt8 commandNumber) + { + return s_commandSizes[commandNumber & ENetProtocolCommand_Mask]; + } + + bool ENetHost::Initialize() + { + std::random_device device; + s_randomGenerator.seed(device()); + s_randomGenerator64.seed(device()); + + return true; + } + + void ENetHost::Uninitialize() + { + } + + std::mt19937 ENetHost::s_randomGenerator; + std::mt19937_64 ENetHost::s_randomGenerator64; +} diff --git a/src/Nazara/Network/ENetPacket.cpp b/src/Nazara/Network/ENetPacket.cpp new file mode 100644 index 000000000..4b4157ac4 --- /dev/null +++ b/src/Nazara/Network/ENetPacket.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2017 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 +{ + /// Temporary + void ENetPacketRef::Reset(ENetPacket* packet) + { + if (m_packet) + { + if (--m_packet->referenceCount == 0) + m_packet->owner->Delete(m_packet); + } + + m_packet = packet; + if (m_packet) + m_packet->referenceCount++; + } +} diff --git a/src/Nazara/Network/ENetPeer.cpp b/src/Nazara/Network/ENetPeer.cpp new file mode 100644 index 000000000..cbae37148 --- /dev/null +++ b/src/Nazara/Network/ENetPeer.cpp @@ -0,0 +1,1349 @@ +/* + Copyright(c) 2002 - 2016 Lee Salzman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Copyright (C) 2017 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 + +namespace Nz +{ + void ENetPeer::Disconnect(UInt32 data) + { + if (m_state == ENetPeerState::Disconnecting || + m_state == ENetPeerState::Disconnected || + m_state == ENetPeerState::AcknowledgingDisconnect || + m_state == ENetPeerState::Zombie) + return; + + ResetQueues(); + + ENetProtocol command(ENetProtocolCommand_Disconnect, 0xFF); + command.disconnect.data = HostToNet(data); + + if (IsConnected()) + command.header.command |= ENetProtocolFlag_Acknowledge; + else + command.header.command |= ENetProtocolFlag_Unsequenced; + + QueueOutgoingCommand(command); + + if (IsConnected()) + { + OnDisconnect(); + + m_state = ENetPeerState::Disconnecting; + } + else + { + m_host->Flush(); + + Reset(); + } + } + + void ENetPeer::DisconnectLater(UInt32 data) + { + if (IsConnected() && HasPendingCommands()) + { + m_state = ENetPeerState::DisconnectLater; + m_eventData = data; + } + else + Disconnect(data); + } + + void ENetPeer::DisconnectNow(UInt32 data) + { + if (m_state == ENetPeerState::Disconnected) + return; + + if (m_state != ENetPeerState::Zombie && m_state != ENetPeerState::Disconnecting) + { + ResetQueues(); + + ENetProtocol command(ENetProtocolCommand_Disconnect | ENetProtocolFlag_Unsequenced, 0xFF); + command.disconnect.data = HostToNet(data); + QueueOutgoingCommand(command); + + m_host->Flush(); + } + + Reset(); + } + + void ENetPeer::Ping() + { + if (m_state != ENetPeerState::Connected) + return; + + ENetProtocol command; + command.header.command = ENetProtocolCommand_Ping | ENetProtocolFlag_Acknowledge; + command.header.channelID = 0xFF; + QueueOutgoingCommand(command); + } + + bool ENetPeer::Receive(ENetPacketRef* packet, UInt8* channelId) + { + if (m_dispatchedCommands.empty()) + return false; + + IncomingCommmand& incomingCommand = m_dispatchedCommands.front(); + + m_totalWaitingData -= incomingCommand.packet->data.GetDataSize(); + + if (packet) + *packet = std::move(incomingCommand.packet); + + if (channelId) + *channelId = incomingCommand.command.header.channelID; + + m_dispatchedCommands.pop_front(); + + return true; + } + + void ENetPeer::Reset() + { + OnDisconnect(); + + m_outgoingPeerID = ENetConstants::ENetProtocol_MaximumPeerId; + m_connectID = 0; + + m_state = ENetPeerState::Disconnected; + + m_incomingBandwidth = 0; + m_outgoingBandwidth = 0; + m_incomingBandwidthThrottleEpoch = 0; + m_outgoingBandwidthThrottleEpoch = 0; + m_incomingDataTotal = 0; + m_outgoingDataTotal = 0; + m_lastSendTime = 0; + m_lastReceiveTime = 0; + m_nextTimeout = 0; + m_earliestTimeout = 0; + m_packetLossEpoch = 0; + m_packetsSent = 0; + m_packetsLost = 0; + m_packetLoss = 0; + m_packetLossVariance = 0; + m_packetThrottle = ENetConstants::ENetProtocol_MaximumWindowSize; + m_packetThrottleLimit = ENetConstants::ENetPeer_PacketThrottleScale; + m_packetThrottleCounter = 0; + m_packetThrottleEpoch = 0; + m_packetThrottleAcceleration = ENetConstants::ENetPeer_PacketThrottleAcceleration; + m_packetThrottleDeceleration = ENetConstants::ENetPeer_PacketThrottleDeceleration; + m_packetThrottleInterval = ENetConstants::ENetPeer_PacketThrottleInterval; + m_pingInterval = ENetConstants::ENetPeer_PingInterval; + m_timeoutLimit = ENetConstants::ENetPeer_TimeoutLimit; + m_timeoutMinimum = ENetConstants::ENetPeer_TimeoutMinimum; + m_timeoutMaximum = ENetConstants::ENetPeer_TimeoutMaximum; + m_lastRoundTripTime = ENetConstants::ENetPeer_DefaultRoundTripTime; + m_lowestRoundTripTime = ENetConstants::ENetPeer_DefaultRoundTripTime; + m_lastRoundTripTimeVariance = 0; + m_highestRoundTripTimeVariance = 0; + m_roundTripTime = ENetConstants::ENetPeer_DefaultRoundTripTime; + m_roundTripTimeVariance = 0; + m_mtu = m_host->m_mtu; + m_reliableDataInTransit = 0; + m_outgoingReliableSequenceNumber = 0; + m_windowSize = ENetConstants::ENetProtocol_MaximumWindowSize; + m_incomingUnsequencedGroup = 0; + m_outgoingUnsequencedGroup = 0; + m_eventData = 0; + m_totalPacketLost = 0; + m_totalPacketSent = 0; + m_totalWaitingData = 0; + + m_unsequencedWindow.fill(0); + + ResetQueues(); + } + + bool ENetPeer::Send(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet) + { + return Send(channelId, m_host->AllocatePacket(flags, std::move(packet))); + } + + void ENetPeer::SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay) + { + NazaraAssert(maxDelay >= minDelay, "Maximum delay cannot be greater than minimum delay"); + + if (packetLossProbability <= 0.0 && minDelay == 0 && maxDelay == 0) + m_isSimulationEnabled = false; + else + { + m_isSimulationEnabled = true; + m_packetDelayDistribution = std::uniform_int_distribution(minDelay, maxDelay); + m_packetLossProbability = std::bernoulli_distribution(packetLossProbability); + } + } + + bool ENetPeer::Send(UInt8 channelId, ENetPacketRef packetRef) + { + if (m_state != ENetPeerState::Connected || channelId >= m_channels.size() || packetRef->data.GetDataSize() > m_host->m_maximumPacketSize) + return false; + + Channel& channel = m_channels[channelId]; + + UInt16 fragmentLength = static_cast(m_mtu - sizeof(ENetProtocolHeader) - sizeof(ENetProtocolSendFragment)); + + UInt32 packetSize = static_cast(packetRef->data.GetDataSize()); + if (packetSize > fragmentLength) + { + UInt32 fragmentCount = (packetSize + fragmentLength - 1) / fragmentLength; + if (fragmentCount > ENetConstants::ENetProtocol_MaximumFragmentCount) + return false; + + UInt8 commandNumber; + UInt16 startSequenceNumber; + if ((packetRef->flags & (ENetPacketFlag_Reliable | ENetPacketFlag_UnreliableFragment)) == ENetPacketFlag_UnreliableFragment && + channel.outgoingUnreliableSequenceNumber < 0xFFFF) + { + commandNumber = ENetProtocolCommand_SendUnreliable; + startSequenceNumber = HostToNet(channel.outgoingUnreliableSequenceNumber + 1); + } + else + { + commandNumber = ENetProtocolCommand_SendFragment | ENetProtocolFlag_Acknowledge; + startSequenceNumber = HostToNet(channel.outgoingReliableSequenceNumber + 1); + } + + for (UInt32 fragmentNumber = 0, fragmentOffset = 0; fragmentOffset < packetSize; ++fragmentNumber, fragmentOffset += fragmentLength) + { + if (packetSize - fragmentOffset < fragmentLength) + fragmentLength = UInt16(packetSize - fragmentOffset); + + OutgoingCommand outgoingCommand; + outgoingCommand.fragmentOffset = fragmentOffset; + outgoingCommand.fragmentLength = fragmentLength; + outgoingCommand.packet = packetRef; + outgoingCommand.command.header.command = commandNumber; + outgoingCommand.command.header.channelID = channelId; + outgoingCommand.command.sendFragment.startSequenceNumber = startSequenceNumber; + outgoingCommand.command.sendFragment.dataLength = HostToNet(fragmentLength); + outgoingCommand.command.sendFragment.fragmentCount = HostToNet(fragmentCount); + outgoingCommand.command.sendFragment.fragmentNumber = HostToNet(fragmentNumber); + outgoingCommand.command.sendFragment.totalLength = HostToNet(packetSize); + outgoingCommand.command.sendFragment.fragmentOffset = HostToNet(fragmentOffset); + + SetupOutgoingCommand(outgoingCommand); + } + + return true; + } + + ENetProtocol command; + command.header.channelID = channelId; + + if ((packetRef->flags & (ENetPacketFlag_Reliable | ENetPacketFlag_Unsequenced)) == ENetPacketFlag_Unsequenced) + { + command.header.command = ENetProtocolCommand_SendUnsequenced | ENetProtocolFlag_Unsequenced; + command.sendUnsequenced.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + } + else if (packetRef->flags & ENetPacketFlag_Reliable || channel.outgoingUnreliableSequenceNumber >= 0xFFFF) + { + command.header.command = ENetProtocolCommand_SendReliable | ENetProtocolFlag_Acknowledge; + command.sendReliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + } + else + { + command.header.command = ENetProtocolCommand_SendUnreliable; + command.sendUnreliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + } + + QueueOutgoingCommand(command, packetRef, 0, packetSize); + + return true; + } + + void ENetPeer::ThrottleConfigure(UInt32 interval, UInt32 acceleration, UInt32 deceleration) + { + m_packetThrottleInterval = interval; + m_packetThrottleAcceleration = acceleration; + m_packetThrottleDeceleration = deceleration; + + ENetProtocol command(ENetProtocolCommand_ThrottleConfigure | ENetProtocolFlag_Acknowledge, 0xFF); + command.throttleConfigure.packetThrottleInterval = HostToNet(interval); + command.throttleConfigure.packetThrottleAcceleration = HostToNet(acceleration); + command.throttleConfigure.packetThrottleDeceleration = HostToNet(deceleration); + QueueOutgoingCommand(command); + } + + bool ENetPeer::CheckTimeouts(ENetEvent* event) + { + UInt32 serviceTime = m_host->GetServiceTime(); + + auto it = m_sentReliableCommands.begin(); + for (; it != m_sentReliableCommands.end();) + { + OutgoingCommand& command = *it; + + if (ENetTimeDifference(serviceTime, command.sentTime) < command.roundTripTimeout) + { + ++it; + continue; + } + + if (m_earliestTimeout == 0 || ENetTimeLess(command.sentTime, m_earliestTimeout)) + m_earliestTimeout = command.sentTime; + + if (m_earliestTimeout != 0 && (ENetTimeDifference(serviceTime, m_earliestTimeout) >= m_timeoutMaximum || + (command.roundTripTimeout >= command.roundTripTimeoutLimit && ENetTimeDifference(serviceTime, m_earliestTimeout) >= m_timeoutMinimum))) + { + m_host->NotifyDisconnect(this, event); + return true; + } + + if (command.packet) + m_reliableDataInTransit -= command.fragmentLength; + + ++m_packetsLost; + ++m_totalPacketLost; + + // http://lists.cubik.org/pipermail/enet-discuss/2014-May/002308.html + command.roundTripTimeout = m_roundTripTime + 4 * m_roundTripTimeVariance; + command.roundTripTimeoutLimit = m_timeoutLimit * command.roundTripTimeout; + + m_outgoingReliableCommands.emplace_front(std::move(command)); + it = m_sentReliableCommands.erase(it); + + // Okay this should just never procs, I don't see how it would be possible + /*if (currentCommand == enet_list_begin(&peer->sentReliableCommands) && + !enet_list_empty(&peer->sentReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout; + }*/ + } + + return false; + } + + void ENetPeer::DispatchState(ENetPeerState state) + { + ChangeState(state); + + m_host->AddToDispatchQueue(this); + } + + void ENetPeer::DispatchIncomingReliableCommands(Channel& channel) + { + auto currentCommand = channel.incomingReliableCommands.begin(); + for (; currentCommand != channel.incomingReliableCommands.end(); ++currentCommand) + { + IncomingCommmand& incomingCommand = *currentCommand; + + if (incomingCommand.fragmentsRemaining > 0 || incomingCommand.reliableSequenceNumber != (channel.incomingReliableSequenceNumber + 1)) + break; + + channel.incomingReliableSequenceNumber = incomingCommand.reliableSequenceNumber; + + if (incomingCommand.fragments.GetSize() > 0) + channel.incomingReliableSequenceNumber += incomingCommand.fragments.GetSize() - 1; + } + + if (currentCommand == channel.incomingReliableCommands.begin()) + return; + + channel.incomingUnreliableSequenceNumber = 0; + + m_dispatchedCommands.splice(m_dispatchedCommands.end(), channel.incomingReliableCommands, channel.incomingReliableCommands.begin(), currentCommand); + + m_host->AddToDispatchQueue(this); + + if (!channel.incomingUnreliableCommands.empty()) + DispatchIncomingUnreliableCommands(channel); + } + + void ENetPeer::DispatchIncomingUnreliableCommands(Channel& channel) + { + std::list::iterator currentCommand; + std::list::iterator droppedCommand; + std::list::iterator startCommand; + + for (droppedCommand = startCommand = currentCommand = channel.incomingUnreliableCommands.begin(); + currentCommand != channel.incomingUnreliableCommands.end(); + ++currentCommand) + { + IncomingCommmand& incomingCommand = *currentCommand; + + if ((incomingCommand.command.header.command & ENetProtocolCommand_Mask) == ENetProtocolCommand_SendUnsequenced) + continue; + + if (incomingCommand.reliableSequenceNumber == channel.incomingReliableSequenceNumber) + { + if (incomingCommand.fragmentsRemaining <= 0) + { + channel.incomingUnreliableSequenceNumber = incomingCommand.unreliableSequenceNumber; + continue; + } + + if (startCommand != currentCommand) + { + m_dispatchedCommands.splice(m_dispatchedCommands.end(), channel.incomingUnreliableCommands, startCommand, currentCommand); + + m_host->AddToDispatchQueue(this); + + droppedCommand = currentCommand; + } + else if (droppedCommand != currentCommand) + { + droppedCommand = currentCommand; + --droppedCommand; + } + } + else + { + UInt16 reliableWindow = incomingCommand.reliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + UInt16 currentWindow = channel.incomingReliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + + if (incomingCommand.reliableSequenceNumber < channel.incomingReliableSequenceNumber) + reliableWindow += ENetConstants::ENetPeer_ReliableWindows; + + if (reliableWindow >= currentWindow && reliableWindow < currentWindow + ENetConstants::ENetPeer_ReliableWindowSize - 1) + break; + + droppedCommand = currentCommand; + ++droppedCommand; + + if (startCommand != currentCommand) + { + m_dispatchedCommands.splice(m_dispatchedCommands.end(), channel.incomingUnreliableCommands, startCommand, currentCommand); + + m_host->AddToDispatchQueue(this); + } + } + + startCommand = currentCommand; + ++startCommand; + } + + if (startCommand != currentCommand) + { + m_dispatchedCommands.splice(m_dispatchedCommands.end(), channel.incomingUnreliableCommands, startCommand, currentCommand); + + m_host->AddToDispatchQueue(this); + + droppedCommand = currentCommand; + } + + channel.incomingUnreliableCommands.erase(channel.incomingUnreliableCommands.begin(), droppedCommand); + } + + bool ENetPeer::HandleAcknowledge(const ENetProtocol* command, ENetEvent* event) + { + if (m_state == ENetPeerState::Disconnected || m_state == ENetPeerState::Zombie) + return true; + + UInt32 serviceTime = m_host->GetServiceTime(); + + UInt32 receivedSentTime = NetToHost(command->acknowledge.receivedSentTime); + receivedSentTime |= serviceTime & 0xFFFF0000; + if ((receivedSentTime & 0x8000) > (serviceTime & 0x8000)) + receivedSentTime -= 0x10000; + + if (ENetTimeLess(serviceTime, receivedSentTime)) + return true; + + m_lastReceiveTime = serviceTime; + m_earliestTimeout = 0; + + UInt32 roundTripTime = ENetTimeDifference(serviceTime, receivedSentTime); + + Throttle(roundTripTime); + + m_roundTripTimeVariance -= m_roundTripTimeVariance / 4; + + if (roundTripTime >= m_roundTripTime) + { + m_roundTripTime += (roundTripTime - m_roundTripTime) / 8; + m_roundTripTimeVariance += (roundTripTime - m_roundTripTime) / 4; + } + else + { + m_roundTripTime -= (m_roundTripTime - roundTripTime) / 8; + m_roundTripTimeVariance += (m_roundTripTime - roundTripTime) / 4; + } + + m_lowestRoundTripTime = std::min(m_lowestRoundTripTime, m_roundTripTime); + m_highestRoundTripTimeVariance = std::max(m_highestRoundTripTimeVariance, m_roundTripTimeVariance); + + if (m_packetThrottleEpoch == 0 || ENetTimeDifference(serviceTime, m_packetThrottleEpoch) >= m_packetThrottleInterval) + { + m_lastRoundTripTime = m_lowestRoundTripTime; + m_lastRoundTripTimeVariance = m_highestRoundTripTimeVariance; + m_lowestRoundTripTime = m_roundTripTime; + m_highestRoundTripTimeVariance = m_roundTripTimeVariance; + m_packetThrottleEpoch = serviceTime; + } + + UInt16 receivedReliableSequenceNumber = NetToHost(command->acknowledge.receivedReliableSequenceNumber); + + ENetProtocolCommand commandNumber = RemoveSentReliableCommand(receivedReliableSequenceNumber, command->header.channelID); + + switch (m_state) + { + case ENetPeerState::AcknowledgingConnect: + if (commandNumber != ENetProtocolCommand_VerifyConnect) + return false; + + m_host->NotifyConnect(this, event, true); + break; + + case ENetPeerState::Disconnecting: + if (commandNumber != ENetProtocolCommand_Disconnect) + return false; + + m_host->NotifyDisconnect(this, event); + break; + + case ENetPeerState::DisconnectLater: + if (!HasPendingCommands()) + Disconnect(m_eventData); + + break; + + default: + break; + } + + return true; + } + + bool ENetPeer::HandleBandwidthLimit(const ENetProtocol* command) + { + if (!IsConnected()) + return false; + + if (m_incomingBandwidth != 0) + --m_host->m_bandwidthLimitedPeers; + + m_incomingBandwidth = NetToHost(command->bandwidthLimit.incomingBandwidth); + m_outgoingBandwidth = NetToHost(command->bandwidthLimit.outgoingBandwidth); + + if (m_incomingBandwidth != 0) + ++m_host->m_bandwidthLimitedPeers; + + if (m_incomingBandwidth == 0 && m_host->m_outgoingBandwidth == 0) + m_windowSize = ENetConstants::ENetProtocol_MaximumWindowSize; + else + { + if (m_incomingBandwidth == 0 || m_host->m_outgoingBandwidth == 0) + m_windowSize = (std::max(m_incomingBandwidth, m_host->m_outgoingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize; + else + m_windowSize = (std::min(m_incomingBandwidth, m_host->m_outgoingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize; + + m_windowSize = Clamp(m_windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize); + } + + return true; + } + + bool ENetPeer::HandleDisconnect(const ENetProtocol* command) + { + if (m_state == ENetPeerState::Disconnected || m_state == ENetPeerState::Zombie || m_state == ENetPeerState::AcknowledgingDisconnect) + return true; + + ResetQueues(); + + if (m_state == ENetPeerState::ConnectionSucceeded || m_state == ENetPeerState::Disconnecting || m_state == ENetPeerState::Connecting) + DispatchState(ENetPeerState::Zombie); + else + { + if (!IsConnected()) + { + if (m_state == ENetPeerState::ConnectionPending) + m_host->m_recalculateBandwidthLimits = true; + + Reset(); + } + else + { + if (command->header.command & ENetProtocolFlag_Acknowledge) + ChangeState(ENetPeerState::AcknowledgingDisconnect); + else + DispatchState(ENetPeerState::Zombie); + } + } + + if (m_state != ENetPeerState::Disconnected) + m_eventData = NetToHost(command->disconnect.data); + + return true; + } + + bool ENetPeer::HandlePing(const ENetProtocol* /*command*/) + { + if (!IsConnected()) + return false; + + return true; + } + + bool ENetPeer::HandleSendFragment(const ENetProtocol* command, UInt8** data) + { + if (command->header.channelID >= m_channels.size() || !IsConnected()) + return false; + + UInt16 fragmentLength = NetToHost(command->sendFragment.dataLength); + *data += fragmentLength; + if (fragmentLength >= m_host->m_maximumPacketSize || *data < m_host->m_receivedData || *data > &m_host->m_receivedData[m_host->m_receivedDataLength]) + return false; + + ENetPeer::Channel& channel = m_channels[command->header.channelID]; + UInt32 startSequenceNumber = NetToHost(command->sendFragment.startSequenceNumber); + UInt16 startWindow = startSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + UInt16 currentWindow = channel.incomingReliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + + if (startSequenceNumber < channel.incomingReliableSequenceNumber) + startWindow += ENetConstants::ENetPeer_ReliableWindows; + + if (startWindow < currentWindow || startWindow >= currentWindow + ENetConstants::ENetPeer_FreeReliableWindows - 1) + return true; + + UInt32 fragmentNumber = NetToHost(command->sendFragment.fragmentNumber); + UInt32 fragmentCount = NetToHost(command->sendFragment.fragmentCount); + UInt32 fragmentOffset = NetToHost(command->sendFragment.fragmentOffset); + UInt32 totalLength = NetToHost(command->sendFragment.totalLength); + + if (fragmentCount > ENetConstants::ENetProtocol_MaximumFragmentCount || fragmentNumber >= fragmentCount || totalLength > m_host->m_maximumPacketSize || + fragmentOffset >= totalLength || fragmentLength > totalLength - fragmentOffset) + return false; + + ENetPeer::IncomingCommmand* startCommand = nullptr; + for (auto currentCommand = channel.incomingReliableCommands.rbegin(); currentCommand != channel.incomingReliableCommands.rend(); ++currentCommand) + { + ENetPeer::IncomingCommmand& incomingCommand = *currentCommand; + + if (startSequenceNumber >= channel.incomingReliableSequenceNumber) + { + if (incomingCommand.reliableSequenceNumber < channel.incomingReliableSequenceNumber) + continue; + } + else if (incomingCommand.reliableSequenceNumber >= channel.incomingReliableSequenceNumber) + break; + + if (incomingCommand.reliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand.reliableSequenceNumber < startSequenceNumber) + break; + + if ((incomingCommand.command.header.command & ENetProtocolCommand_Mask) != ENetProtocolCommand_SendFragment || + totalLength != incomingCommand.packet->data.GetDataSize() || fragmentCount != incomingCommand.fragments.GetSize()) + return false; + + startCommand = &incomingCommand; + break; + } + } + + if (!startCommand) + { + ENetProtocol hostCommand = *command; + hostCommand.header.reliableSequenceNumber = startSequenceNumber; + + startCommand = QueueIncomingCommand(hostCommand, nullptr, totalLength, ENetPacketFlag_Reliable, fragmentCount); + if (!startCommand) + return false; + } + + if (!startCommand->fragments.Test(fragmentNumber)) + { + --startCommand->fragmentsRemaining; + + startCommand->fragments.Set(fragmentNumber, true); + + if (fragmentOffset + fragmentLength > startCommand->packet->data.GetDataSize()) + fragmentLength = static_cast(startCommand->packet->data.GetDataSize() - fragmentOffset); + + std::memcpy(startCommand->packet->data.GetData() + NetPacket::HeaderSize + fragmentOffset, reinterpret_cast(command) + sizeof(ENetProtocolSendFragment), fragmentLength); + + if (startCommand->fragmentsRemaining <= 0) + DispatchIncomingReliableCommands(channel); + } + + return true; + } + + bool ENetPeer::HandleSendReliable(const ENetProtocol* command, UInt8** data) + { + if (command->header.channelID >= m_channels.size() || !IsConnected()) + return false; + + UInt16 dataLength = NetToHost(command->sendReliable.dataLength); + *data += dataLength; + if (dataLength >= m_host->m_maximumPacketSize || *data < m_host->m_receivedData || *data > &m_host->m_receivedData[m_host->m_receivedDataLength]) + return false; + + if (!QueueIncomingCommand(*command, reinterpret_cast(command) + sizeof(ENetProtocolSendReliable), dataLength, ENetPacketFlag_Reliable, 0)) + return false; + + return true; + } + + bool ENetPeer::HandleSendUnreliable(const ENetProtocol* command, UInt8** data) + { + if (command->header.channelID >= m_channels.size() || !IsConnected()) + return false; + + UInt16 dataLength = NetToHost(command->sendUnreliable.dataLength); + *data += dataLength; + if (dataLength >= m_host->m_maximumPacketSize || *data < m_host->m_receivedData || *data > &m_host->m_receivedData[m_host->m_receivedDataLength]) + return false; + + if (!QueueIncomingCommand(*command, reinterpret_cast(command) + sizeof(ENetProtocolSendUnreliable), dataLength, 0, 0)) + return false; + + return true; + } + + bool ENetPeer::HandleSendUnreliableFragment(const ENetProtocol* command, UInt8** data) + { + if (command->header.channelID >= m_channels.size() || !IsConnected()) + return false; + + UInt16 fragmentLength = NetToHost(command->sendFragment.dataLength); + *data += fragmentLength; + if (fragmentLength >= m_host->m_maximumPacketSize || *data < m_host->m_receivedData || *data > &m_host->m_receivedData[m_host->m_receivedDataLength]) + return false; + + ENetPeer::Channel& channel = m_channels[command->header.channelID]; + UInt32 reliableSequenceNumber = command->header.reliableSequenceNumber; + UInt32 startSequenceNumber = NetToHost(command->sendFragment.startSequenceNumber); + + UInt16 reliableWindow = reliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + UInt16 currentWindow = channel.incomingReliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + + if (startSequenceNumber < channel.incomingReliableSequenceNumber) + reliableWindow += ENetConstants::ENetPeer_ReliableWindows; + + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENetConstants::ENetPeer_FreeReliableWindows - 1) + return true; + + if (reliableSequenceNumber == channel.incomingReliableSequenceNumber && startSequenceNumber <= channel.incomingUnreliableSequenceNumber) + return true; + + UInt32 fragmentNumber = NetToHost(command->sendFragment.fragmentNumber); + UInt32 fragmentCount = NetToHost(command->sendFragment.fragmentCount); + UInt32 fragmentOffset = NetToHost(command->sendFragment.fragmentOffset); + UInt32 totalLength = NetToHost(command->sendFragment.totalLength); + + if (fragmentCount > ENetConstants::ENetProtocol_MaximumFragmentCount || fragmentNumber >= fragmentCount || totalLength > m_host->m_maximumPacketSize || + fragmentOffset >= totalLength || fragmentLength > totalLength - fragmentOffset) + return false; + + ENetPeer::IncomingCommmand* startCommand = nullptr; + for (auto currentCommand = channel.incomingUnreliableCommands.rbegin(); currentCommand != channel.incomingUnreliableCommands.rend(); ++currentCommand) + { + ENetPeer::IncomingCommmand& incomingCommand = *currentCommand; + + if (startSequenceNumber >= channel.incomingReliableSequenceNumber) + { + if (incomingCommand.reliableSequenceNumber < channel.incomingReliableSequenceNumber) + continue; + } + else if (incomingCommand.reliableSequenceNumber >= channel.incomingReliableSequenceNumber) + break; + + if (incomingCommand.reliableSequenceNumber < reliableSequenceNumber) + break; + + if (incomingCommand.reliableSequenceNumber > reliableSequenceNumber) + continue; + + if (incomingCommand.unreliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand.unreliableSequenceNumber < startSequenceNumber) + break; + + if ((incomingCommand.command.header.command & ENetProtocolCommand_Mask) != ENetProtocolCommand_SendUnreliableFragment || + totalLength != incomingCommand.packet->data.GetDataSize() || fragmentCount != incomingCommand.fragments.GetSize()) + return false; + + startCommand = &incomingCommand; + break; + } + } + + if (startCommand) + { + if (!QueueIncomingCommand(*command, nullptr, totalLength, ENetPacketFlag_UnreliableFragment, fragmentCount)) + return false; + } + + if (!startCommand->fragments.Test(fragmentNumber)) + { + --startCommand->fragmentsRemaining; + + startCommand->fragments.Set(fragmentNumber, true); + + if (fragmentOffset + fragmentLength > startCommand->packet->data.GetDataSize()) + fragmentLength = static_cast(startCommand->packet->data.GetDataSize() - fragmentOffset); + + std::memcpy(startCommand->packet->data.GetData() + NetPacket::HeaderSize + fragmentOffset, reinterpret_cast(command) + sizeof(ENetProtocolSendFragment), fragmentLength); + + if (startCommand->fragmentsRemaining <= 0) + DispatchIncomingUnreliableCommands(channel); + } + + return true; + } + + bool ENetPeer::HandleSendUnsequenced(const ENetProtocol* command, UInt8** data) + { + if (command->header.channelID >= m_channels.size() || !IsConnected()) + return false; + + std::size_t dataLength = NetToHost(command->sendUnsequenced.dataLength); + *data += dataLength; + if (dataLength >= m_host->m_maximumPacketSize || *data < m_host->m_receivedData || *data > &m_host->m_receivedData[m_host->m_receivedDataLength]) + return false; + + UInt32 unsequencedGroup = NetToHost(command->sendUnsequenced.unsequencedGroup); + UInt32 index = unsequencedGroup % ENetConstants::ENetPeer_UnsequencedWindowSize; + + if (unsequencedGroup < m_incomingUnsequencedGroup) + unsequencedGroup += 0x10000; + + if (unsequencedGroup >= static_cast(m_incomingUnsequencedGroup) + ENetConstants::ENetPeer_UnsequencedWindows * ENetConstants::ENetPeer_UnsequencedWindowSize) + return true; + + unsequencedGroup &= 0xFFFF; + + if (unsequencedGroup - index != m_incomingUnsequencedGroup) + { + m_incomingUnsequencedGroup = unsequencedGroup - index; + + m_unsequencedWindow.fill(0); + } + else if (m_unsequencedWindow[index / 32] & (1 << (index % 32))) + return true; + + if (!QueueIncomingCommand(*command, reinterpret_cast(command) + sizeof(ENetProtocolSendUnsequenced), dataLength, ENetPacketFlag_Unsequenced, 0)) + return false; + + m_unsequencedWindow[index / 32] |= 1 << (index % 32); + + return true; + } + + bool ENetPeer::HandleThrottleConfigure(const ENetProtocol* command) + { + if (!IsConnected()) + return false; + + m_packetThrottleInterval = NetToHost(command->throttleConfigure.packetThrottleInterval); + m_packetThrottleAcceleration = NetToHost(command->throttleConfigure.packetThrottleAcceleration); + m_packetThrottleDeceleration = NetToHost(command->throttleConfigure.packetThrottleDeceleration); + + return true; + } + + bool ENetPeer::HandleVerifyConnect(const ENetProtocol* command, ENetEvent* event) + { + if (m_state != ENetPeerState::Connecting) + return true; + + UInt32 channelCount = NetToHost(command->verifyConnect.channelCount); + + if (channelCount < ENetConstants::ENetProtocol_MinimumChannelCount || channelCount > ENetConstants::ENetProtocol_MaximumChannelCount || + NetToHost(command->verifyConnect.packetThrottleInterval) != m_packetThrottleInterval || + NetToHost(command->verifyConnect.packetThrottleAcceleration) != m_packetThrottleAcceleration || + NetToHost(command->verifyConnect.packetThrottleDeceleration) != m_packetThrottleDeceleration || + command->verifyConnect.connectID != m_connectID) + { + m_eventData = 0; + + DispatchState(ENetPeerState::Zombie); + + return false; + } + + RemoveSentReliableCommand(1, 0xFF); + + if (channelCount < m_channels.size()) + m_channels.resize(channelCount); + + m_outgoingPeerID = NetToHost(command->verifyConnect.outgoingPeerID); + m_incomingSessionID = command->verifyConnect.incomingSessionID; + m_outgoingSessionID = command->verifyConnect.outgoingSessionID; + + UInt32 mtu = Clamp(NetToHost(command->verifyConnect.mtu), ENetConstants::ENetProtocol_MinimumMTU, ENetConstants::ENetProtocol_MaximumMTU); + m_mtu = std::min(m_mtu, mtu); + + UInt32 windowSize = Clamp(NetToHost(command->verifyConnect.windowSize), ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize); + m_windowSize = std::min(m_windowSize, windowSize); + + m_incomingBandwidth = NetToHost(command->verifyConnect.incomingBandwidth); + m_outgoingBandwidth = NetToHost(command->verifyConnect.outgoingBandwidth); + + m_host->NotifyConnect(this, event, false); + return true; + } + + void ENetPeer::InitIncoming(std::size_t channelCount, const IpAddress& address, ENetProtocolConnect& incomingCommand) + { + m_channels.resize(channelCount); + m_address = address; + + m_connectID = incomingCommand.connectID; + m_eventData = NetToHost(incomingCommand.data); + m_incomingBandwidth = NetToHost(incomingCommand.incomingBandwidth); + m_outgoingBandwidth = NetToHost(incomingCommand.outgoingBandwidth); + m_packetThrottleInterval = NetToHost(incomingCommand.packetThrottleInterval); + m_packetThrottleAcceleration = NetToHost(incomingCommand.packetThrottleAcceleration); + m_packetThrottleDeceleration = NetToHost(incomingCommand.packetThrottleDeceleration); + m_outgoingPeerID = NetToHost(incomingCommand.outgoingPeerID); + m_state = ENetPeerState::AcknowledgingConnect; + + UInt8 incomingSessionId, outgoingSessionId; + + incomingSessionId = incomingCommand.incomingSessionID == 0xFF ? m_outgoingSessionID : incomingCommand.incomingSessionID; + incomingSessionId = (incomingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift); + if (incomingSessionId == m_outgoingSessionID) + incomingSessionId = (incomingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift); + m_outgoingSessionID = incomingSessionId; + + outgoingSessionId = incomingCommand.outgoingSessionID == 0xFF ? m_incomingSessionID : incomingCommand.outgoingSessionID; + outgoingSessionId = (outgoingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift); + if (outgoingSessionId == m_incomingSessionID) + outgoingSessionId = (outgoingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift); + m_incomingSessionID = outgoingSessionId; + + m_mtu = Clamp(NetToHost(incomingCommand.mtu), ENetConstants::ENetProtocol_MinimumMTU, ENetConstants::ENetProtocol_MaximumMTU); + + if (m_host->m_outgoingBandwidth == 0 && m_incomingBandwidth == 0) + m_windowSize = ENetConstants::ENetProtocol_MaximumWindowSize; + else if (m_host->m_outgoingBandwidth == 0 || m_incomingBandwidth == 0) + m_windowSize = (std::max(m_host->m_outgoingBandwidth, m_incomingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize; + else + m_windowSize = (std::min(m_host->m_outgoingBandwidth, m_incomingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize; + + m_windowSize = Clamp(m_windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize); + } + + void ENetPeer::InitOutgoing(std::size_t channelCount, const IpAddress& address, UInt32 connectId, UInt32 windowSize) + { + m_channels.resize(channelCount); + + m_address = address; + m_connectID = connectId; + m_state = ENetPeerState::Connecting; + m_windowSize = Clamp(windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize); + } + + void ENetPeer::OnConnect() + { + if (!IsConnected()) + { + if (m_incomingBandwidth != 0) + ++m_host->m_bandwidthLimitedPeers; + + ++m_host->m_connectedPeers; + } + } + + void ENetPeer::OnDisconnect() + { + if (IsConnected()) + { + if (m_incomingBandwidth != 0) + --m_host->m_bandwidthLimitedPeers; + + --m_host->m_connectedPeers; + } + } + + ENetProtocolCommand ENetPeer::RemoveSentReliableCommand(UInt16 reliableSequenceNumber, UInt8 channelId) + { + std::list* commandList = nullptr; + + bool found = false; + auto currentCommand = m_sentReliableCommands.begin(); + commandList = &m_sentReliableCommands; + for (; currentCommand != m_sentReliableCommands.end(); ++currentCommand) + { + found = true; + + if (currentCommand->reliableSequenceNumber == reliableSequenceNumber && + currentCommand->command.header.channelID == channelId) + break; + } + + bool wasSent = true; + if (currentCommand == m_sentReliableCommands.end()) + { + currentCommand = m_outgoingReliableCommands.begin(); + commandList = &m_outgoingReliableCommands; + for (; currentCommand != m_outgoingReliableCommands.end(); ++currentCommand) + { + found = true; + + if (currentCommand->sendAttempts < 1) + return ENetProtocolCommand_None; + + if (currentCommand->reliableSequenceNumber == reliableSequenceNumber && + currentCommand->command.header.channelID == channelId) + break; + } + + if (currentCommand == m_outgoingReliableCommands.end()) + return ENetProtocolCommand_None; + + wasSent = false; + } + + if (!found) //< Really useful? + return ENetProtocolCommand_None; + + if (channelId < m_channels.size()) + { + Channel& channel = m_channels[channelId]; + + UInt16 reliableWindow = reliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + if (channel.reliableWindows[reliableWindow] > 0) + { + --channel.reliableWindows[reliableWindow]; + if (!channel.reliableWindows[reliableWindow]) + channel.usedReliableWindows &= ~(1 << reliableWindow); + } + } + + ENetProtocolCommand commandNumber = static_cast(currentCommand->command.header.command & ENetProtocolCommand_Mask); + + if (currentCommand->packet && wasSent) + m_reliableDataInTransit -= currentCommand->fragmentLength; + + commandList->erase(currentCommand); + + if (m_sentReliableCommands.empty()) + return commandNumber; + + currentCommand = m_sentReliableCommands.begin(); + m_nextTimeout = currentCommand->sentTime + currentCommand->roundTripTimeout; + + return commandNumber; + } + + void ENetPeer::RemoveSentUnreliableCommands() + { + m_sentUnreliableCommands.clear(); + } + + void ENetPeer::ResetQueues() + { + m_host->RemoveFromDispatchQueue(this); + + m_acknowledgements.clear(); + m_dispatchedCommands.clear(); + m_outgoingReliableCommands.clear(); + m_outgoingUnreliableCommands.clear(); + m_sentReliableCommands.clear(); + m_sentUnreliableCommands.clear(); + + m_channels.clear(); + } + + bool ENetPeer::QueueAcknowledgement(ENetProtocol*command, UInt16 sentTime) + { + if (command->header.channelID < m_channels.size()) + { + Channel& channel = m_channels[command->header.channelID]; + + UInt16 reliableWindow = command->header.reliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + UInt16 currentWindow = channel.incomingReliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + + if (command->header.reliableSequenceNumber < channel.incomingReliableSequenceNumber) + reliableWindow += ENetConstants::ENetPeer_ReliableWindows; + + if (reliableWindow >= currentWindow + ENetConstants::ENetPeer_FreeReliableWindows - 1 && reliableWindow <= currentWindow + ENetConstants::ENetPeer_FreeReliableWindows) + return false; + } + + Acknowledgement acknowledgment; + acknowledgment.command = *command; + acknowledgment.sentTime = sentTime; + + m_outgoingDataTotal += sizeof(Acknowledgement); + + m_acknowledgements.emplace_back(acknowledgment); + + return true; + } + + ENetPeer::IncomingCommmand* ENetPeer::QueueIncomingCommand(const ENetProtocol& command, const void* data, std::size_t dataLength, UInt32 flags, UInt32 fragmentCount) + { + static IncomingCommmand dummyCommand; + + UInt32 reliableSequenceNumber = 0; + UInt32 unreliableSequenceNumber = 0; + UInt16 reliableWindow; + UInt16 currentWindow; + + auto discardCommand = [&]() -> IncomingCommmand* + { + if (fragmentCount > 0) + return nullptr; //< Error + + return &dummyCommand; + }; + + if (m_state == ENetPeerState::DisconnectLater) + return discardCommand(); + + Channel& channel = m_channels[command.header.channelID]; + + if ((command.header.command & ENetProtocolCommand_Mask) != ENetProtocolCommand_SendUnsequenced) + { + reliableSequenceNumber = command.header.reliableSequenceNumber; + reliableWindow = reliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + currentWindow = channel.incomingReliableSequenceNumber / ENetConstants::ENetPeer_ReliableWindowSize; + + if (reliableSequenceNumber < channel.incomingReliableSequenceNumber) + reliableWindow += ENetConstants::ENetPeer_ReliableWindows; + + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENetConstants::ENetPeer_FreeReliableWindows - 1) + return discardCommand(); + } + + std::list* commandList = nullptr; + std::list::reverse_iterator currentCommand; + + switch (command.header.command & ENetProtocolCommand_Mask) + { + case ENetProtocolCommand_SendFragment: + case ENetProtocolCommand_SendReliable: + { + if (reliableSequenceNumber == channel.incomingReliableSequenceNumber) + return discardCommand(); + + commandList = &channel.incomingReliableCommands; + + for (currentCommand = channel.incomingReliableCommands.rbegin(); currentCommand != channel.incomingReliableCommands.rend(); ++currentCommand) + { + IncomingCommmand& incomingCommand = *currentCommand; + + if (reliableSequenceNumber >= channel.incomingReliableSequenceNumber) + { + if (incomingCommand.reliableSequenceNumber < channel.incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand.reliableSequenceNumber >= channel.incomingReliableSequenceNumber) + break; + + if (incomingCommand.reliableSequenceNumber <= reliableSequenceNumber) + { + if (incomingCommand.reliableSequenceNumber < reliableSequenceNumber) + break; + + return discardCommand(); + } + } + break; + } + + case ENetProtocolCommand_SendUnreliable: + case ENetProtocolCommand_SendUnreliableFragment: + { + unreliableSequenceNumber = NetToHost(command.sendUnreliable.unreliableSequenceNumber); + + if (reliableSequenceNumber == channel.incomingReliableSequenceNumber && unreliableSequenceNumber <= channel.incomingUnreliableSequenceNumber) + return discardCommand(); + + commandList = &channel.incomingUnreliableCommands; + + for (currentCommand = channel.incomingUnreliableCommands.rbegin(); currentCommand != channel.incomingUnreliableCommands.rend(); ++currentCommand) + { + IncomingCommmand& incomingCommand = *currentCommand; + + if ((command.header.command & ENetProtocolCommand_Mask) == ENetProtocolCommand_SendUnsequenced) //< wtf + continue; + + if (reliableSequenceNumber >= channel.incomingReliableSequenceNumber) + { + if (incomingCommand.reliableSequenceNumber < channel.incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand.reliableSequenceNumber >= channel.incomingReliableSequenceNumber) + break; + + if (incomingCommand.reliableSequenceNumber < reliableSequenceNumber) + break; + + if (incomingCommand.reliableSequenceNumber > reliableSequenceNumber) + continue; + + if (incomingCommand.unreliableSequenceNumber <= unreliableSequenceNumber) + { + if (incomingCommand.unreliableSequenceNumber < unreliableSequenceNumber) + break; + + return discardCommand(); + } + } + break; + } + + case ENetProtocolCommand_SendUnsequenced: + { + commandList = &channel.incomingUnreliableCommands; + + currentCommand = channel.incomingUnreliableCommands.rend(); + break; + } + + default: + return discardCommand(); + } + + if (m_totalWaitingData >= m_host->m_maximumWaitingData) + return nullptr; + + ENetPacketRef packet = m_host->AllocatePacket(flags); + packet->data.Reset(0, data, dataLength); + + IncomingCommmand incomingCommand; + incomingCommand.reliableSequenceNumber = command.header.reliableSequenceNumber; + incomingCommand.unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; + incomingCommand.command = command; + incomingCommand.packet = packet; + incomingCommand.fragments.Resize(fragmentCount); + incomingCommand.fragmentsRemaining = fragmentCount; + + if (packet) + m_totalWaitingData += packet->data.GetDataSize(); + + auto it = commandList->insert(currentCommand.base(), incomingCommand); + + switch (command.header.command & ENetProtocolCommand_Mask) + { + case ENetProtocolCommand_SendFragment: + case ENetProtocolCommand_SendReliable: + DispatchIncomingReliableCommands(channel); + break; + + default: + DispatchIncomingUnreliableCommands(channel); + break; + } + + return &(*it); + } + + void ENetPeer::QueueOutgoingCommand(ENetProtocol& command, ENetPacketRef packet, UInt32 offset, UInt16 length) + { + OutgoingCommand outgoingCommand; + outgoingCommand.command = command; + outgoingCommand.fragmentLength = length; + outgoingCommand.fragmentOffset = offset; + outgoingCommand.packet = packet; + + SetupOutgoingCommand(outgoingCommand); + } + + void ENetPeer::SetupOutgoingCommand(OutgoingCommand& outgoingCommand) + { + m_outgoingDataTotal += static_cast(ENetHost::GetCommandSize(outgoingCommand.command.header.command) + outgoingCommand.fragmentLength); + + if (outgoingCommand.command.header.channelID == 0xFF) + { + ++m_outgoingReliableSequenceNumber; + + outgoingCommand.reliableSequenceNumber = m_outgoingReliableSequenceNumber; + outgoingCommand.unreliableSequenceNumber = 0; + } + else + { + Channel* channel = &m_channels[outgoingCommand.command.header.channelID]; + if (outgoingCommand.command.header.command & ENetProtocolFlag_Acknowledge) + { + ++channel->outgoingReliableSequenceNumber; + channel->outgoingUnreliableSequenceNumber = 0; + + outgoingCommand.reliableSequenceNumber = channel->outgoingReliableSequenceNumber; + outgoingCommand.unreliableSequenceNumber = 0; + } + else if (outgoingCommand.command.header.command & ENetProtocolFlag_Unsequenced) + { + ++m_outgoingUnsequencedGroup; + + outgoingCommand.reliableSequenceNumber = 0; + outgoingCommand.unreliableSequenceNumber = 0; + } + else + { + if (outgoingCommand.fragmentOffset == 0) + ++channel->outgoingUnreliableSequenceNumber; + + outgoingCommand.reliableSequenceNumber = channel->outgoingReliableSequenceNumber; + outgoingCommand.unreliableSequenceNumber = channel->outgoingUnreliableSequenceNumber; + } + } + + outgoingCommand.sendAttempts = 0; + outgoingCommand.sentTime = 0; + outgoingCommand.roundTripTimeout = 0; + outgoingCommand.roundTripTimeoutLimit = 0; + outgoingCommand.command.header.reliableSequenceNumber = HostToNet(outgoingCommand.reliableSequenceNumber); + + switch (outgoingCommand.command.header.command & ENetProtocolCommand_Mask) + { + case ENetProtocolCommand_SendUnreliable: + outgoingCommand.command.sendUnreliable.unreliableSequenceNumber = HostToNet(outgoingCommand.unreliableSequenceNumber); + break; + + case ENetProtocolCommand_SendUnsequenced: + outgoingCommand.command.sendUnsequenced.unsequencedGroup = HostToNet(m_outgoingUnsequencedGroup); + break; + + default: + break; + } + + if (outgoingCommand.command.header.command & ENetProtocolFlag_Acknowledge) + m_outgoingReliableCommands.emplace_back(outgoingCommand); + else + m_outgoingUnreliableCommands.emplace_back(outgoingCommand); + } + + int ENetPeer::Throttle(UInt32 rtt) + { + if (m_lastRoundTripTime <= m_lastRoundTripTimeVariance) + m_packetThrottle = m_packetThrottleLimit; + else + { + if (rtt < m_lastRoundTripTime) + { + m_packetThrottle = std::max(m_packetThrottle + m_packetThrottleAcceleration, m_packetThrottleLimit); + return 1; + } + else if (rtt > m_lastRoundTripTime + 2 * m_lastRoundTripTimeVariance) + { + if (m_packetThrottle > m_packetThrottleDeceleration) + m_packetThrottle -= m_packetThrottleDeceleration; + else + m_packetThrottle = 0; + + return -1; + } + } + + return 0; + } +} diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index 29be756ea..fc63be189 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/Linux/SocketPollerImpl.cpp b/src/Nazara/Network/Linux/SocketPollerImpl.cpp index c839d7352..6617efd37 100644 --- a/src/Nazara/Network/Linux/SocketPollerImpl.cpp +++ b/src/Nazara/Network/Linux/SocketPollerImpl.cpp @@ -23,13 +23,19 @@ namespace Nz void SocketPollerImpl::Clear() { - m_activeSockets.clear(); + m_readyToReadSockets.clear(); + m_readyToWriteSockets.clear(); m_sockets.clear(); } - bool SocketPollerImpl::IsReady(SocketHandle socket) const + bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const { - return m_activeSockets.count(socket) != 0; + return m_readyToReadSockets.count(socket) != 0; + } + + bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const + { + return m_readyToWriteSockets.count(socket) != 0; } bool SocketPollerImpl::IsRegistered(SocketHandle socket) const @@ -37,15 +43,21 @@ namespace Nz return m_sockets.count(socket) != 0; } - bool SocketPollerImpl::RegisterSocket(SocketHandle socket) + bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags) { NazaraAssert(!IsRegistered(socket), "Socket is already registered"); - epoll_event event; - event.events = EPOLLIN; - event.data.fd = socket; + epoll_event entry; + entry.events = 0; + entry.data.fd = socket; - if (epoll_ctl(m_handle, EPOLL_CTL_ADD, socket, &event) != 0) + if (eventFlags & SocketPollEvent_Read) + entry.events |= EPOLLIN; + + if (eventFlags & SocketPollEvent_Write) + entry.events |= EPOLLOUT; + + if (epoll_ctl(m_handle, EPOLL_CTL_ADD, socket, &entry) != 0) { NazaraError("Failed to add socket to epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')'); return false; @@ -60,7 +72,8 @@ namespace Nz { NazaraAssert(IsRegistered(socket), "Socket is not registered"); - m_activeSockets.erase(socket); + m_readyToReadSockets.erase(socket); + m_readyToWriteSockets.erase(socket); m_sockets.erase(socket); if (epoll_ctl(m_handle, EPOLL_CTL_DEL, socket, nullptr) != 0) @@ -84,21 +97,27 @@ namespace Nz return 0; } - m_activeSockets.clear(); + m_readyToReadSockets.clear(); + m_readyToWriteSockets.clear(); if (activeSockets > 0) { int socketCount = activeSockets; for (int i = 0; i < socketCount; ++i) { - if (m_events[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR)) + if (m_events[i].events & (EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLERR)) { - m_activeSockets.insert(m_events[i].data.fd); + if (m_events[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR)) + m_readyToReadSockets.insert(m_events[i].data.fd); + + if (m_events[i].events & (EPOLLOUT | EPOLLERR)) + m_readyToWriteSockets.insert(m_events[i].data.fd); + if (m_events[i].events & EPOLLERR) NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll with EPOLLERR status"); } else { - NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll without EPOLLIN (events: 0x" + String::Number(m_events[i].events, 16) + ')'); + NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll without EPOLLIN nor EPOLLOUT flags (events: 0x" + String::Number(m_events[i].events, 16) + ')'); activeSockets--; } } diff --git a/src/Nazara/Network/Linux/SocketPollerImpl.hpp b/src/Nazara/Network/Linux/SocketPollerImpl.hpp index 1c54471fc..a804102fa 100644 --- a/src/Nazara/Network/Linux/SocketPollerImpl.hpp +++ b/src/Nazara/Network/Linux/SocketPollerImpl.hpp @@ -23,16 +23,18 @@ namespace Nz void Clear(); - bool IsReady(SocketHandle socket) const; + bool IsReadyToRead(SocketHandle socket) const; + bool IsReadyToWrite(SocketHandle socket) const; bool IsRegistered(SocketHandle socket) const; - bool RegisterSocket(SocketHandle socket); + bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags); void UnregisterSocket(SocketHandle socket); int Wait(UInt64 msTimeout, SocketError* error); private: - std::unordered_set m_activeSockets; + std::unordered_set m_readyToReadSockets; + std::unordered_set m_readyToWriteSockets; std::unordered_set m_sockets; std::vector m_events; int m_handle; diff --git a/src/Nazara/Network/NetPacket.cpp b/src/Nazara/Network/NetPacket.cpp index 900170b89..0dda7c864 100644 --- a/src/Nazara/Network/NetPacket.cpp +++ b/src/Nazara/Network/NetPacket.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp index 3e798e681..57ddfd83b 100644 --- a/src/Nazara/Network/Network.cpp +++ b/src/Nazara/Network/Network.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/Posix/SocketImpl.cpp b/src/Nazara/Network/Posix/SocketImpl.cpp index 954ac4f43..be6f84581 100644 --- a/src/Nazara/Network/Posix/SocketImpl.cpp +++ b/src/Nazara/Network/Posix/SocketImpl.cpp @@ -5,10 +5,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -277,7 +279,7 @@ namespace Nz bool SocketImpl::QueryBroadcasting(SocketHandle handle, SocketError* error) { bool code; - unsigned int codeLength = sizeof(code); + socklen_t codeLength = sizeof(code); if (getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &code, &codeLength) == SOCKET_ERROR) { @@ -296,7 +298,7 @@ namespace Nz bool SocketImpl::QueryKeepAlive(SocketHandle handle, SocketError* error) { bool code; - unsigned int codeLength = sizeof(code); + socklen_t codeLength = sizeof(code); if (getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &code, &codeLength) == SOCKET_ERROR) { @@ -315,14 +317,14 @@ namespace Nz std::size_t SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) { unsigned int code; - unsigned int codeLength = sizeof(code); + socklen_t codeLength = sizeof(code); if (getsockopt(handle, IPPROTO_IP, IP_MTU, &code, &codeLength) == SOCKET_ERROR) { if (error) *error = TranslateErrnoToResolveError(GetLastErrorCode()); - return -1; + return 0; } if (error) @@ -334,7 +336,7 @@ namespace Nz bool SocketImpl::QueryNoDelay(SocketHandle handle, SocketError* error) { bool code; - unsigned int codeLength = sizeof(code); + socklen_t codeLength = sizeof(code); if (getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &code, &codeLength) == SOCKET_ERROR) { @@ -350,6 +352,25 @@ namespace Nz return code; } + std::size_t SocketImpl::QueryReceiveBufferSize(SocketHandle handle, SocketError* error) + { + unsigned int code; + socklen_t codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return 0; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + IpAddress SocketImpl::QueryPeerAddress(SocketHandle handle, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); @@ -371,6 +392,25 @@ namespace Nz return IpAddressImpl::FromSockAddr(reinterpret_cast(nameBuffer.data())); } + std::size_t SocketImpl::QuerySendBufferSize(SocketHandle handle, SocketError* error) + { + unsigned int code; + socklen_t codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return 0; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + IpAddress SocketImpl::QuerySocketAddress(SocketHandle handle, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); @@ -425,6 +465,9 @@ namespace Nz if (byteRead == SOCKET_ERROR) { int errorCode = GetLastErrorCode(); + if (errorCode == EAGAIN) + errorCode = EWOULDBLOCK; + switch (errorCode) { case EWOULDBLOCK: @@ -474,6 +517,9 @@ namespace Nz if (byteRead == SOCKET_ERROR) { int errorCode = GetLastErrorCode(); + if (errorCode == EAGAIN) + errorCode = EWOULDBLOCK; + switch (errorCode) { case EWOULDBLOCK: @@ -523,10 +569,24 @@ namespace Nz int byteSent = send(handle, reinterpret_cast(buffer), length, 0); if (byteSent == SOCKET_ERROR) { - if (error) - *error = TranslateErrnoToResolveError(GetLastErrorCode()); + int errorCode = GetLastErrorCode(); + if (errorCode == EAGAIN) + errorCode = EWOULDBLOCK; - return false; //< Error + switch (errorCode) + { + case EWOULDBLOCK: + byteSent = 0; + break; + + default: + { + if (error) + *error = TranslateErrnoToResolveError(errorCode); + + return false; //< Error + } + } } if (sent) @@ -538,6 +598,60 @@ namespace Nz return true; } + bool SocketImpl::SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffers && bufferCount > 0, "Invalid buffers"); + + StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(iovec)); + struct iovec* sysBuffers = static_cast(memory.GetPtr()); + for (std::size_t i = 0; i < bufferCount; ++i) + { + sysBuffers[i].iov_base = buffers[i].data; + sysBuffers[i].iov_len = buffers[i].dataLength; + } + + struct msghdr msgHdr; + std::memset(&msgHdr, 0, sizeof(msgHdr)); + + IpAddressImpl::SockAddrBuffer nameBuffer; + msgHdr.msg_namelen = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); + msgHdr.msg_name = nameBuffer.data(); + msgHdr.msg_iov = sysBuffers; + msgHdr.msg_iovlen = static_cast(bufferCount); + + int byteSent = sendmsg(handle, &msgHdr, MSG_NOSIGNAL); + if (byteSent == SOCKET_ERROR) + { + int errorCode = GetLastErrorCode(); + if (errorCode == EAGAIN) + errorCode = EWOULDBLOCK; + + switch (errorCode) + { + case EWOULDBLOCK: + byteSent = 0; + break; + + default: + { + if (error) + *error = TranslateErrnoToResolveError(errorCode); + + return false; //< Error + } + } + } + + if (sent) + *sent = static_cast(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"); @@ -549,10 +663,24 @@ namespace Nz int byteSent = sendto(handle, reinterpret_cast(buffer), length, 0, reinterpret_cast(nameBuffer.data()), bufferLength); if (byteSent == SOCKET_ERROR) { - if (error) - *error = TranslateErrnoToResolveError(GetLastErrorCode()); + int errorCode = GetLastErrorCode(); + if (errorCode == EAGAIN) + errorCode = EWOULDBLOCK; - return false; //< Error + switch (errorCode) + { + case EWOULDBLOCK: + byteSent = 0; + break; + + default: + { + if (error) + *error = TranslateErrnoToResolveError(errorCode); + + return false; //< Error + } + } } if (sent) @@ -659,6 +787,44 @@ namespace Nz return true; } + bool SocketImpl::SetReceiveBufferSize(SocketHandle handle, std::size_t size, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + int option = static_cast(size); + if (setsockopt(handle, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateErrnoToResolveError(GetLastErrorCode()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetSendBufferSize(SocketHandle handle, std::size_t size, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + int option = static_cast(size); + if (setsockopt(handle, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&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) diff --git a/src/Nazara/Network/Posix/SocketImpl.hpp b/src/Nazara/Network/Posix/SocketImpl.hpp index c120bd19a..7ee2e24f6 100644 --- a/src/Nazara/Network/Posix/SocketImpl.hpp +++ b/src/Nazara/Network/Posix/SocketImpl.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #define NAZARA_NETWORK_POLL_SUPPORT 1 @@ -55,6 +56,8 @@ namespace Nz 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 std::size_t QueryReceiveBufferSize(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QuerySendBufferSize(SocketHandle handle, SocketError* error = nullptr); static int Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error); @@ -62,12 +65,15 @@ namespace Nz 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 SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, 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 bool SetReceiveBufferSize(SocketHandle handle, std::size_t size, SocketError* error = nullptr); + static bool SetSendBufferSize(SocketHandle handle, std::size_t size, SocketError* error = nullptr); static SocketError TranslateErrnoToResolveError(int error); static int TranslateNetProtocolToAF(NetProtocol protocol); @@ -83,4 +89,4 @@ namespace Nz }; } -#endif // NAZARA_SOCKETIMPL_HPP \ No newline at end of file +#endif // NAZARA_SOCKETIMPL_HPP diff --git a/src/Nazara/Network/Posix/SocketPollerImpl.cpp b/src/Nazara/Network/Posix/SocketPollerImpl.cpp index 5d2a6c317..59b8a8ca7 100644 --- a/src/Nazara/Network/Posix/SocketPollerImpl.cpp +++ b/src/Nazara/Network/Posix/SocketPollerImpl.cpp @@ -10,14 +10,20 @@ namespace Nz { void SocketPollerImpl::Clear() { - m_activeSockets.clear(); + m_readyToReadSockets.clear(); + m_readyToWriteSockets.clear(); m_allSockets.clear(); m_sockets.clear(); } - bool SocketPollerImpl::IsReady(SocketHandle socket) const + bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const { - return m_activeSockets.count(socket) != 0; + return m_readyToReadSockets.count(socket) != 0; + } + + bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const + { + return m_readyToWriteSockets.count(socket) != 0; } bool SocketPollerImpl::IsRegistered(SocketHandle socket) const @@ -25,16 +31,22 @@ namespace Nz return m_allSockets.count(socket) != 0; } - bool SocketPollerImpl::RegisterSocket(SocketHandle socket) + bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags) { NazaraAssert(!IsRegistered(socket), "Socket is already registered"); PollSocket entry = { socket, - POLLRDNORM, + 0, 0 }; + if (eventFlags & SocketPollEvent_Read) + entry.events |= POLLRDNORM; + + if (eventFlags & SocketPollEvent_Write) + entry.events |= POLLWRNORM; + m_allSockets[socket] = m_sockets.size(); m_sockets.emplace_back(entry); @@ -57,10 +69,11 @@ namespace Nz // Now move it properly (lastElement is invalid after the following line) and pop it m_sockets[entry] = std::move(m_sockets.back()); } - m_sockets.pop_back(); - m_activeSockets.erase(socket); + m_allSockets.erase(socket); + m_readyToReadSockets.erase(socket); + m_readyToWriteSockets.erase(socket); } int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error) @@ -68,20 +81,25 @@ namespace Nz int activeSockets; // Reset status of sockets - for (PollSocket& entry : m_sockets) - entry.revents = 0; - activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast(msTimeout), error); - m_activeSockets.clear(); - if (activeSockets > 0) + m_readyToReadSockets.clear(); + m_readyToWriteSockets.clear(); + if (activeSockets > 0U) { int socketRemaining = activeSockets; for (PollSocket& entry : m_sockets) { - if (entry.revents & POLLRDNORM) + if (entry.revents != 0) { - m_activeSockets.insert(entry.fd); + if (entry.revents & POLLRDNORM) + m_readyToReadSockets.insert(entry.fd); + + if (entry.revents & POLLWRNORM) + m_readyToWriteSockets.insert(entry.fd); + + entry.revents = 0; + if (--socketRemaining == 0) break; } diff --git a/src/Nazara/Network/Posix/SocketPollerImpl.hpp b/src/Nazara/Network/Posix/SocketPollerImpl.hpp index 3472c3265..3582121d4 100644 --- a/src/Nazara/Network/Posix/SocketPollerImpl.hpp +++ b/src/Nazara/Network/Posix/SocketPollerImpl.hpp @@ -27,13 +27,14 @@ namespace Nz bool IsReady(SocketHandle socket) const; bool IsRegistered(SocketHandle socket) const; - bool RegisterSocket(SocketHandle socket); + bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags); void UnregisterSocket(SocketHandle socket); int Wait(UInt64 msTimeout, SocketError* error); private: - std::unordered_set m_activeSockets; + std::unordered_set m_readyToReadSockets; + std::unordered_set m_readyToWriteSockets; std::unordered_map m_allSockets; std::vector m_sockets; }; diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp index 1b374d604..3667eb113 100644 --- a/src/Nazara/Network/RUdpConnection.cpp +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -527,7 +527,7 @@ namespace Nz } else { - NazaraNotice("Received wrong token (" + String::Number(token) + " instead of " + String::Number(~peer.stateData1) + ") from client " + peer.address); + NazaraNotice("Received wrong token (" + String::Number(token) + " instead of " + String::Number(~peer.stateData1) + ") from client " + peer.address.ToString()); return; //< Ignore } diff --git a/src/Nazara/Network/SocketPoller.cpp b/src/Nazara/Network/SocketPoller.cpp index 049970433..7ef261ef9 100644 --- a/src/Nazara/Network/SocketPoller.cpp +++ b/src/Nazara/Network/SocketPoller.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -57,12 +57,13 @@ namespace Nz /*! * \brief Checks if a specific socket is ready to read data * - * This function allows you to read the results of the last Wait operation and if a specific socket is ready. + * This function allows you to read the results of the last Wait operation and if a specific socket is ready to read (has incoming data). * - * A socket in the ready state (with the exception of TcpServer) has incoming data and can be read without blocking. + * A socket in the ready to read state (with the exception of TcpServer) has incoming data and can be read without blocking. * - * \remark When used on a TcpServer socket, this function returns true if the server is ready to accept a new client. - * \remark You must call Wait before using this function in order to refresh the state. + * \remark You must call Wait before using this function in order to refresh the read state. + * \remark A socket must be registered with SocketPollerEvent_Read event flag for its read state to be watched + * \remark A TcpServer socket becomes ready to read when it is ready to accept a new client. * * \param socket Reference to the socket to check * @@ -70,11 +71,32 @@ namespace Nz * * \see Wait */ - bool SocketPoller::IsReady(const AbstractSocket& socket) const + bool SocketPoller::IsReadyToRead(const AbstractSocket& socket) const { NazaraAssert(IsRegistered(socket), "Socket is not registered in the poller"); - return m_impl->IsReady(socket.GetNativeHandle()); + return m_impl->IsReadyToRead(socket.GetNativeHandle()); + } + + /*! + * \brief Checks if a specific socket is ready to write data + * + * This function allows you to read the results of the last Wait operation and if a specific socket is ready to write (can be written to without blocking). + * + * \remark You must call Wait before using this function in order to refresh the read state. + * \remark A socket must be registered with SocketPollerEvent_Write event flag for its read state to be watched + * + * \param socket Reference to the socket to check + * + * \return True if the socket is available for writing without blocking, false otherwise + * + * \see Wait + */ + bool SocketPoller::IsReadyToWrite(const AbstractSocket& socket) const + { + NazaraAssert(IsRegistered(socket), "Socket is not registered in the poller"); + + return m_impl->IsReadyToWrite(socket.GetNativeHandle()); } /*! @@ -97,7 +119,7 @@ namespace Nz /*! * \brief Register a socket in the SocketPoller * - * A registered socket is part of the SocketPoller and will be checked by the next Wait operations. + * A registered socket is part of the SocketPoller and will be checked by the next Wait operations according to the event flags passed when registered. * * The SocketPoller keeps a reference to the internal handle of registered socket, which should not be freed while it is registered in the SocketPooler. * @@ -107,17 +129,18 @@ namespace Nz * \remark The socket should not be freed while it is registered in the SocketPooler. * * \param socket Reference to the socket to register + * \param eventFlags Socket events to watch * * \return True if the socket is registered, false otherwise * * \see IsRegistered * \see UnregisterSocket */ - bool SocketPoller::RegisterSocket(AbstractSocket& socket) + bool SocketPoller::RegisterSocket(AbstractSocket& socket, SocketPollEventFlags eventFlags) { NazaraAssert(!IsRegistered(socket), "This socket is already registered in this SocketPoller"); - return m_impl->RegisterSocket(socket.GetNativeHandle()); + return m_impl->RegisterSocket(socket.GetNativeHandle(), eventFlags); } /*! @@ -142,13 +165,15 @@ namespace Nz } /*! - * \brief Wait until any registered socket switches to a ready state + * \brief Wait until any registered socket switches to a ready state. * * Waits a specific/undetermined amount of time until at least one socket part of the SocketPoller becomes ready. - * To query the ready state of the registered socket, use the IsReady function. + * To query the ready state of the registered socket, use the IsReadyToRead or IsReadyToWrite functions. * * \param msTimeout Maximum time to wait in milliseconds, 0 for infinity * + * \return True if at least one socket registered to the poller is ready. + * * \remark It is an error to try to unregister a non-registered socket from a SocketPoller. * * \see IsReady diff --git a/src/Nazara/Network/SystemSocket.hpp b/src/Nazara/Network/SystemSocket.hpp index 95b7dff37..df71c43c7 100644 --- a/src/Nazara/Network/SystemSocket.hpp +++ b/src/Nazara/Network/SystemSocket.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 2be3d44cf..9e2eb7e0c 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -326,7 +326,7 @@ namespace Nz }); } - while (totalByteSent < size) + while (totalByteSent < size || !IsBlockingEnabled()) { int sendSize = static_cast(std::min(size - totalByteSent, std::numeric_limits::max())); //< Handle very large send int sentSize; @@ -353,6 +353,45 @@ namespace Nz return true; } + /*! + * \brief Sends multiple buffers at once + * \return true If data were sent + * + * \param buffers A pointer to an array of NetBuffer containing buffers and size data + * \param size Number of NetBuffer to send + * \param sent Optional argument to get the number of bytes sent + */ + bool TcpClient::SendMultiple(const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent) + { + NazaraAssert(buffers && bufferCount > 0, "Invalid buffer"); + + int byteSent; + if (!SocketImpl::SendMultiple(m_handle, buffers, bufferCount, m_peerAddress, &byteSent, &m_lastError)) + { + switch (m_lastError) + { + case SocketError_ConnectionClosed: + case SocketError_ConnectionRefused: + UpdateState(SocketState_NotConnected); + break; + + default: + break; + } + + if (sent) + *sent = byteSent; + + return false; + } + + if (sent) + *sent = byteSent; + + UpdateState(SocketState_Connected); + return true; + } + /*! * \brief Sends the packet available * \return true If packet sent diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp index 7a33c066b..95aaaf098 100644 --- a/src/Nazara/Network/TcpServer.cpp +++ b/src/Nazara/Network/TcpServer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index b49aedcf3..bc86f8401 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -17,6 +17,12 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::UdpSocket + * \brief Network class that represents a UDP socket, allowing for sending/receiving datagrams. + */ + /*! * \brief Binds a specific IpAddress * \return State of the socket @@ -93,7 +99,18 @@ namespace Nz int read; if (!SocketImpl::ReceiveFrom(m_handle, buffer, static_cast(size), from, &read, &m_lastError)) - return false; + { + switch (m_lastError) + { + case SocketError_ConnectionClosed: + m_lastError = SocketError_NoError; + read = 0; + break; + + default: + return false; + } + } if (received) *received = read; @@ -179,6 +196,31 @@ namespace Nz return true; } + /*! + * \brief Sends multiple buffers as one datagram + * \return true If data were sent + * + * \param to Destination IpAddress (must match socket protocol) + * \param buffers A pointer to an array of NetBuffer containing buffers and size data + * \param size Number of NetBuffer to send + * \param sent Optional argument to get the number of bytes sent + */ + bool UdpSocket::SendMultiple(const IpAddress& to, const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent) + { + NazaraAssert(to.IsValid(), "Invalid ip address"); + NazaraAssert(to.GetProtocol() == m_protocol, "IP Address has a different protocol than the socket"); + NazaraAssert(buffers && bufferCount > 0, "Invalid buffer"); + + int byteSent; + if (!SocketImpl::SendMultiple(m_handle, buffers, bufferCount, to, &byteSent, &m_lastError)) + return false; + + if (sent) + *sent = byteSent; + + return true; + } + /*! * \brief Sends the packet available * \return true If packet sent diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 2dac156ce..992b075a9 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp index e85dc7411..3415906d9 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.hpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 5a02b4bae..32404f53a 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -1,10 +1,11 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 #if defined(NAZARA_COMPILER_MINGW) && __GNUC__ < 5 @@ -331,7 +332,7 @@ namespace Nz std::size_t SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) { - unsigned int code; + DWORD code; int codeLength = sizeof(code); if (getsockopt(handle, SOL_SOCKET, SO_MAX_MSG_SIZE, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) @@ -339,7 +340,7 @@ namespace Nz if (error) *error = TranslateWSAErrorToSocketError(WSAGetLastError()); - return -1; + return 0; } if (error) @@ -367,6 +368,25 @@ namespace Nz return code == TRUE; } + std::size_t SocketImpl::QueryReceiveBufferSize(SocketHandle handle, SocketError* error) + { + DWORD code; + int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return 0; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + IpAddress SocketImpl::QueryPeerAddress(SocketHandle handle, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); @@ -415,6 +435,25 @@ namespace Nz return IpAddressImpl::FromSockAddr(reinterpret_cast(nameBuffer.data())); } + std::size_t SocketImpl::QuerySendBufferSize(SocketHandle handle, SocketError* error) + { + DWORD code; + int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return 0; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + int SocketImpl::Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error) { NazaraAssert(fdarray && nfds > 0, "Invalid fdarray"); @@ -555,10 +594,23 @@ namespace Nz int byteSent = send(handle, reinterpret_cast(buffer), length, 0); if (byteSent == SOCKET_ERROR) { - if (error) - *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + int errorCode = WSAGetLastError(); + switch (errorCode) + { + case WSAEWOULDBLOCK: + { + byteSent = 0; + break; + } - return false; //< Error + default: + { + if (error) + *error = TranslateWSAErrorToSocketError(errorCode); + + return false; //< Error + } + } } if (sent) @@ -570,6 +622,53 @@ namespace Nz return true; } + bool SocketImpl::SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffers && bufferCount > 0, "Invalid buffers"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); + + StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(WSABUF)); + WSABUF* winBuffers = static_cast(memory.GetPtr()); + for (std::size_t i = 0; i < bufferCount; ++i) + { + winBuffers[i].buf = static_cast(buffers[i].data); + winBuffers[i].len = static_cast(buffers[i].dataLength); + } + + DWORD byteSent; + if (WSASendTo(handle, winBuffers, static_cast(bufferCount), &byteSent, 0, reinterpret_cast(nameBuffer.data()), bufferLength, nullptr, nullptr) == SOCKET_ERROR) + { + int errorCode = WSAGetLastError(); + switch (errorCode) + { + case WSAEWOULDBLOCK: + { + byteSent = 0; + break; + } + + default: + { + if (error) + *error = TranslateWSAErrorToSocketError(errorCode); + + return false; //< Error + } + } + } + + if (sent) + *sent = static_cast(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"); @@ -581,10 +680,23 @@ namespace Nz int byteSent = sendto(handle, reinterpret_cast(buffer), length, 0, reinterpret_cast(nameBuffer.data()), bufferLength); if (byteSent == SOCKET_ERROR) { - if (error) - *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + int errorCode = WSAGetLastError(); + switch (errorCode) + { + case WSAEWOULDBLOCK: + { + byteSent = 0; + break; + } - return false; //< Error + default: + { + if (error) + *error = TranslateWSAErrorToSocketError(errorCode); + + return false; //< Error + } + } } if (sent) @@ -677,6 +789,44 @@ namespace Nz return true; } + bool SocketImpl::SetReceiveBufferSize(SocketHandle handle, std::size_t size, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + DWORD option = static_cast(size); + if (setsockopt(handle, SOL_SOCKET, SO_RCVBUF, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetSendBufferSize(SocketHandle handle, std::size_t size, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + DWORD option = static_cast(size); + if (setsockopt(handle, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + SocketError SocketImpl::TranslateWSAErrorToSocketError(int error) { switch (error) diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp index 94e2e9a8c..edcc7ce09 100644 --- a/src/Nazara/Network/Win32/SocketImpl.hpp +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -7,9 +7,10 @@ #ifndef NAZARA_SOCKETIMPL_HPP #define NAZARA_SOCKETIMPL_HPP -#include #include #include +#include +#include #include #define NAZARA_NETWORK_POLL_SUPPORT NAZARA_CORE_WINDOWS_NT6 @@ -34,7 +35,7 @@ namespace Nz 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); @@ -54,8 +55,10 @@ namespace Nz static bool QueryKeepAlive(SocketHandle handle, SocketError* error = nullptr); static std::size_t QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); static bool QueryNoDelay(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QueryReceiveBufferSize(SocketHandle handle, SocketError* error = nullptr); static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); + static std::size_t QuerySendBufferSize(SocketHandle handle, SocketError* error = nullptr); static int Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error); @@ -63,12 +66,15 @@ namespace Nz 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 SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, 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 bool SetReceiveBufferSize(SocketHandle handle, std::size_t size, SocketError* error = nullptr); + static bool SetSendBufferSize(SocketHandle handle, std::size_t size, SocketError* error = nullptr); static SocketError TranslateWSAErrorToSocketError(int error); static int TranslateNetProtocolToAF(NetProtocol protocol); @@ -83,4 +89,4 @@ namespace Nz }; } -#endif // NAZARA_SOCKETIMPL_HPP \ No newline at end of file +#endif // NAZARA_SOCKETIMPL_HPP diff --git a/src/Nazara/Network/Win32/SocketPollerImpl.cpp b/src/Nazara/Network/Win32/SocketPollerImpl.cpp index dd80c233d..b6dee66e9 100644 --- a/src/Nazara/Network/Win32/SocketPollerImpl.cpp +++ b/src/Nazara/Network/Win32/SocketPollerImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -10,29 +10,43 @@ namespace Nz SocketPollerImpl::SocketPollerImpl() { #if !NAZARA_NETWORK_POLL_SUPPORT - FD_ZERO(&m_activeSockets); - FD_ZERO(&m_sockets); + FD_ZERO(&m_readSockets); + FD_ZERO(&m_readyToReadSockets); + FD_ZERO(&m_readyToWriteSockets); + FD_ZERO(&m_writeSockets); #endif } void SocketPollerImpl::Clear() { #if NAZARA_NETWORK_POLL_SUPPORT - m_activeSockets.clear(); m_allSockets.clear(); + m_readyToReadSockets.clear(); + m_readyToWriteSockets.clear(); m_sockets.clear(); #else - FD_ZERO(&m_activeSockets); - FD_ZERO(&m_sockets); + FD_ZERO(&m_readSockets); + FD_ZERO(&m_readyToReadSockets); + FD_ZERO(&m_readyToWriteSockets); + FD_ZERO(&m_writeSockets); #endif } - bool SocketPollerImpl::IsReady(SocketHandle socket) const + bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const { #if NAZARA_NETWORK_POLL_SUPPORT - return m_activeSockets.count(socket) != 0; + return m_readyToReadSockets.count(socket) != 0; #else - return FD_ISSET(socket, &m_activeSockets) != 0; + return FD_ISSET(socket, &m_readyToReadSockets) != 0; + #endif + } + + bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const + { + #if NAZARA_NETWORK_POLL_SUPPORT + return m_readyToWriteSockets.count(socket) != 0; + #else + return FD_ISSET(socket, &m_readyToWriteSockets) != 0; #endif } @@ -41,31 +55,45 @@ namespace Nz #if NAZARA_NETWORK_POLL_SUPPORT return m_allSockets.count(socket) != 0; #else - return FD_ISSET(socket, &m_sockets) != 0; + return FD_ISSET(socket, &m_readSockets) != 0 || + FD_ISSET(socket, &m_writeSockets) != 0; #endif } - bool SocketPollerImpl::RegisterSocket(SocketHandle socket) + bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags) { NazaraAssert(!IsRegistered(socket), "Socket is already registered"); #if NAZARA_NETWORK_POLL_SUPPORT PollSocket entry = { socket, - POLLRDNORM, + 0, 0 }; + if (eventFlags & SocketPollEvent_Read) + entry.events |= POLLRDNORM; + + if (eventFlags & SocketPollEvent_Write) + entry.events |= POLLWRNORM; + m_allSockets[socket] = m_sockets.size(); m_sockets.emplace_back(entry); #else - if (m_sockets.fd_count > FD_SETSIZE) + for (std::size_t i = 0; i < 2; ++i) { - NazaraError("Socket count exceeding FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")"); - return false; - } + if ((eventFlags & ((i == 0) ? SocketPollEvent_Read : SocketPollEvent_Write)) == 0) + continue; - FD_SET(socket, &m_sockets); + fd_set& targetSet = (i == 0) ? m_readSockets : m_writeSockets; + if (targetSet.fd_count > FD_SETSIZE) + { + NazaraError("Socket count exceeding hard-coded FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")"); + return false; + } + + FD_SET(socket, &targetSet); + } #endif return true; @@ -88,13 +116,16 @@ namespace Nz // Now move it properly (lastElement is invalid after the following line) and pop it m_sockets[entry] = std::move(m_sockets.back()); } - m_sockets.pop_back(); - m_activeSockets.erase(socket); + m_allSockets.erase(socket); + m_readyToReadSockets.erase(socket); + m_readyToWriteSockets.erase(socket); #else - FD_CLR(socket, &m_activeSockets); - FD_CLR(socket, &m_sockets); + FD_CLR(socket, &m_readSockets); + FD_CLR(socket, &m_readyToReadSockets); + FD_CLR(socket, &m_readyToWriteSockets); + FD_CLR(socket, &m_writeSockets); #endif } @@ -103,35 +134,52 @@ namespace Nz int activeSockets; #if NAZARA_NETWORK_POLL_SUPPORT - // Reset status of sockets - for (PollSocket& entry : m_sockets) - entry.revents = 0; - activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast(msTimeout), error); - m_activeSockets.clear(); + m_readyToReadSockets.clear(); + m_readyToWriteSockets.clear(); if (activeSockets > 0U) { int socketRemaining = activeSockets; for (PollSocket& entry : m_sockets) { - if (entry.revents & POLLRDNORM) + if (entry.revents != 0) { - m_activeSockets.insert(entry.fd); + if (entry.revents & POLLRDNORM) + m_readyToReadSockets.insert(entry.fd); + + if (entry.revents & POLLWRNORM) + m_readyToWriteSockets.insert(entry.fd); + + entry.revents = 0; + if (--socketRemaining == 0) break; } } } - #else - m_activeSockets = m_sockets; + #else + fd_set* readSet = nullptr; + fd_set* writeSet = nullptr; + + if (m_readSockets.fd_count > 0) + { + m_readyToReadSockets = m_readSockets; + readSet = &m_readyToReadSockets; + } + + if (m_writeSockets.fd_count > 0) + { + m_readyToWriteSockets = m_writeSockets; + readSet = &m_readyToWriteSockets; + } timeval tv; tv.tv_sec = static_cast(msTimeout / 1000ULL); tv.tv_usec = static_cast((msTimeout % 1000ULL) * 1000ULL); - activeSockets = ::select(0xDEADBEEF, &m_activeSockets, nullptr, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows + activeSockets = ::select(0xDEADBEEF, readSet, writeSet, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows if (activeSockets == SOCKET_ERROR) { if (error) diff --git a/src/Nazara/Network/Win32/SocketPollerImpl.hpp b/src/Nazara/Network/Win32/SocketPollerImpl.hpp index a8a45a7de..a94af1372 100644 --- a/src/Nazara/Network/Win32/SocketPollerImpl.hpp +++ b/src/Nazara/Network/Win32/SocketPollerImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -25,24 +25,28 @@ namespace Nz void Clear(); - bool IsReady(SocketHandle socket) const; + bool IsReadyToRead(SocketHandle socket) const; + bool IsReadyToWrite(SocketHandle socket) const; bool IsRegistered(SocketHandle socket) const; - bool RegisterSocket(SocketHandle socket); + bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags); void UnregisterSocket(SocketHandle socket); int Wait(UInt64 msTimeout, SocketError* error); private: #if NAZARA_NETWORK_POLL_SUPPORT - std::unordered_set m_activeSockets; + std::unordered_set m_readyToReadSockets; + std::unordered_set m_readyToWriteSockets; std::unordered_map m_allSockets; std::vector m_sockets; #else - fd_set m_sockets; - fd_set m_activeSockets; + fd_set m_readSockets; + fd_set m_readyToReadSockets; + fd_set m_readyToWriteSockets; + fd_set m_writeSockets; #endif }; } -#endif // NAZARA_SOCKETPOLLERIMPL_HPP \ No newline at end of file +#endif // NAZARA_SOCKETPOLLERIMPL_HPP diff --git a/src/Nazara/Noise/Debug/NewOverload.cpp b/src/Nazara/Noise/Debug/NewOverload.cpp index 1e2da7321..d761e94b8 100644 --- a/src/Nazara/Noise/Debug/NewOverload.cpp +++ b/src/Nazara/Noise/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/FBM.cpp b/src/Nazara/Noise/FBM.cpp index 96126ec60..95d79c2cd 100644 --- a/src/Nazara/Noise/FBM.cpp +++ b/src/Nazara/Noise/FBM.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/HybridMultiFractal.cpp b/src/Nazara/Noise/HybridMultiFractal.cpp index 4278d23b2..86ae2e9cd 100644 --- a/src/Nazara/Noise/HybridMultiFractal.cpp +++ b/src/Nazara/Noise/HybridMultiFractal.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/MixerBase.cpp b/src/Nazara/Noise/MixerBase.cpp index d3dd82acc..f3fbc0f8a 100644 --- a/src/Nazara/Noise/MixerBase.cpp +++ b/src/Nazara/Noise/MixerBase.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Noise.cpp b/src/Nazara/Noise/Noise.cpp index 6cfad09c1..880527834 100644 --- a/src/Nazara/Noise/Noise.cpp +++ b/src/Nazara/Noise/Noise.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index 1dc74595a..0a4f09505 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/NoiseTools.cpp b/src/Nazara/Noise/NoiseTools.cpp index 9cf6efd39..5f6274357 100644 --- a/src/Nazara/Noise/NoiseTools.cpp +++ b/src/Nazara/Noise/NoiseTools.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Perlin.cpp b/src/Nazara/Noise/Perlin.cpp index a400972ff..9d0249759 100644 --- a/src/Nazara/Noise/Perlin.cpp +++ b/src/Nazara/Noise/Perlin.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Simplex.cpp b/src/Nazara/Noise/Simplex.cpp index b1a2bd0b6..d73465c70 100644 --- a/src/Nazara/Noise/Simplex.cpp +++ b/src/Nazara/Noise/Simplex.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Worley.cpp b/src/Nazara/Noise/Worley.cpp index 4f2aa90f7..81fd8aad0 100644 --- a/src/Nazara/Noise/Worley.cpp +++ b/src/Nazara/Noise/Worley.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Rémi Bèges +// Copyright (C) 2017 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics2D/Collider2D.cpp b/src/Nazara/Physics2D/Collider2D.cpp index 986a03ccf..3a679fad9 100644 --- a/src/Nazara/Physics2D/Collider2D.cpp +++ b/src/Nazara/Physics2D/Collider2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -11,6 +11,21 @@ namespace Nz { Collider2D::~Collider2D() = default; + std::vector Collider2D::GenerateShapes(RigidBody2D* body) const + { + cpShapeFilter filter = cpShapeFilterNew(m_collisionGroup, m_categoryMask, m_collisionMask); + + std::vector shapes = CreateShapes(body); + for (cpShape* shape : shapes) + { + cpShapeSetFilter(shape, filter); + cpShapeSetCollisionType(shape, m_collisionId); + cpShapeSetSensor(shape, (m_trigger) ? cpTrue : cpFalse); + } + + return shapes; + } + /******************************** BoxCollider2D *********************************/ BoxCollider2D::BoxCollider2D(const Vector2f& size, float radius) : diff --git a/src/Nazara/Physics2D/Debug/NewOverload.cpp b/src/Nazara/Physics2D/Debug/NewOverload.cpp index 0c82acc94..0bbef36d9 100644 --- a/src/Nazara/Physics2D/Debug/NewOverload.cpp +++ b/src/Nazara/Physics2D/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics2D/PhysWorld2D.cpp b/src/Nazara/Physics2D/PhysWorld2D.cpp index 878a84400..cbf098786 100644 --- a/src/Nazara/Physics2D/PhysWorld2D.cpp +++ b/src/Nazara/Physics2D/PhysWorld2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -37,6 +37,128 @@ namespace Nz return m_stepSize; } + bool PhysWorld2D::NearestBodyQuery(const Vector2f & from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody) + { + cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask); + + if (cpShape* shape = cpSpacePointQueryNearest(m_handle, {from.x, from.y}, maxDistance, filter, nullptr)) + { + if (nearestBody) + *nearestBody = static_cast(cpShapeGetUserData(shape)); + + return true; + } + else + return false; + } + + bool PhysWorld2D::NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result) + { + cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask); + + if (result) + { + cpPointQueryInfo queryInfo; + + if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, &queryInfo)) + { + result->closestPoint.Set(Nz::Vector2(queryInfo.point.x, queryInfo.point.y)); + result->distance = float(queryInfo.distance); + result->fraction.Set(Nz::Vector2(queryInfo.gradient.x, queryInfo.gradient.y)); + result->nearestBody = static_cast(cpShapeGetUserData(shape)); + + return true; + } + else + return false; + } + else + { + if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, nullptr)) + return true; + else + return false; + } + } + + bool PhysWorld2D::RaycastQuery(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector* hitInfos) + { + using ResultType = decltype(hitInfos); + + auto callback = [](cpShape* shape, cpVect point, cpVect normal, cpFloat alpha, void* data) + { + ResultType results = static_cast(data); + + RaycastHit hitInfo; + hitInfo.fraction = float(alpha); + hitInfo.hitNormal.Set(Nz::Vector2(normal.x, normal.y)); + hitInfo.hitPos.Set(Nz::Vector2(point.x, point.y)); + hitInfo.nearestBody = static_cast(cpShapeGetUserData(shape)); + + results->emplace_back(std::move(hitInfo)); + }; + + cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask); + + std::size_t previousSize = hitInfos->size(); + cpSpaceSegmentQuery(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, callback, hitInfos); + + return hitInfos->size() != previousSize; + } + + bool PhysWorld2D::RaycastQueryFirst(const Nz::Vector2f& from, const Nz::Vector2f& to, float radius, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RaycastHit* hitInfo) + { + cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask); + + if (hitInfo) + { + cpSegmentQueryInfo queryInfo; + + if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, &queryInfo)) + { + hitInfo->fraction = float(queryInfo.alpha); + hitInfo->hitNormal.Set(Nz::Vector2(queryInfo.normal.x, queryInfo.normal.y)); + hitInfo->hitPos.Set(Nz::Vector2(queryInfo.point.x, queryInfo.point.y)); + hitInfo->nearestBody = static_cast(cpShapeGetUserData(queryInfo.shape)); + + return true; + } + else + return false; + } + else + { + if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, nullptr)) + return true; + else + return false; + } + } + + void PhysWorld2D::RegionQuery(const Nz::Rectf& boundingBox, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, std::vector* bodies) + { + using ResultType = decltype(bodies); + + auto callback = [] (cpShape* shape, void* data) + { + ResultType results = static_cast(data); + results->push_back(static_cast(cpShapeGetUserData(shape))); + }; + + cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask); + cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y + boundingBox.height, boundingBox.x + boundingBox.width, boundingBox.y), filter, callback, bodies); + } + + void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks) + { + InitCallbacks(cpSpaceAddWildcardHandler(m_handle, collisionId), callbacks); + } + + void PhysWorld2D::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, const Callback& callbacks) + { + InitCallbacks(cpSpaceAddCollisionHandler(m_handle, collisionIdA, collisionIdB), callbacks); + } + void PhysWorld2D::SetGravity(const Vector2f& gravity) { cpSpaceSetGravity(m_handle, cpv(gravity.x, gravity.y)); @@ -53,8 +175,155 @@ namespace Nz while (m_timestepAccumulator >= m_stepSize) { + OnPhysWorld2DPreStep(this); + cpSpaceStep(m_handle, m_stepSize); + + OnPhysWorld2DPostStep(this); + if (!m_rigidPostSteps.empty()) + { + for (const auto& pair : m_rigidPostSteps) + { + for (const auto& step : pair.second.funcs) + step(pair.first); + } + + m_rigidPostSteps.clear(); + } + m_timestepAccumulator -= m_stepSize; } } + + void PhysWorld2D::InitCallbacks(cpCollisionHandler* handler, const Callback& callbacks) + { + auto it = m_callbacks.emplace(handler, std::make_unique(callbacks)).first; + + handler->userData = it->second.get(); + + if (callbacks.startCallback) + { + handler->beginFunc = [](cpArbiter* arb, cpSpace* space, void *data) -> cpBool + { + cpBody* firstBody; + cpBody* secondBody; + cpArbiterGetBodies(arb, &firstBody, &secondBody); + + PhysWorld2D* world = static_cast(cpSpaceGetUserData(space)); + RigidBody2D* firstRigidBody = static_cast(cpBodyGetUserData(firstBody)); + RigidBody2D* secondRigidBody = static_cast(cpBodyGetUserData(secondBody)); + + const Callback* customCallbacks = static_cast(data); + if (customCallbacks->startCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata)) + { + cpBool retA = cpArbiterCallWildcardBeginA(arb, space); + cpBool retB = cpArbiterCallWildcardBeginB(arb, space); + return retA && retB; + } + else + return cpFalse; + }; + } + + if (callbacks.endCallback) + { + handler->separateFunc = [](cpArbiter* arb, cpSpace* space, void *data) + { + cpBody* firstBody; + cpBody* secondBody; + cpArbiterGetBodies(arb, &firstBody, &secondBody); + + PhysWorld2D* world = static_cast(cpSpaceGetUserData(space)); + RigidBody2D* firstRigidBody = static_cast(cpBodyGetUserData(firstBody)); + RigidBody2D* secondRigidBody = static_cast(cpBodyGetUserData(secondBody)); + + const Callback* customCallbacks = static_cast(data); + customCallbacks->endCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata); + + cpArbiterCallWildcardSeparateA(arb, space); + cpArbiterCallWildcardSeparateB(arb, space); + }; + } + + if (callbacks.preSolveCallback) + { + handler->preSolveFunc = [](cpArbiter* arb, cpSpace* space, void *data) -> cpBool + { + cpBody* firstBody; + cpBody* secondBody; + cpArbiterGetBodies(arb, &firstBody, &secondBody); + + PhysWorld2D* world = static_cast(cpSpaceGetUserData(space)); + RigidBody2D* firstRigidBody = static_cast(cpBodyGetUserData(firstBody)); + RigidBody2D* secondRigidBody = static_cast(cpBodyGetUserData(secondBody)); + + const Callback* customCallbacks = static_cast(data); + if (customCallbacks->preSolveCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata)) + { + cpBool retA = cpArbiterCallWildcardPreSolveA(arb, space); + cpBool retB = cpArbiterCallWildcardPreSolveB(arb, space); + return retA && retB; + } + else + return cpFalse; + }; + } + + if (callbacks.postSolveCallback) + { + handler->postSolveFunc = [](cpArbiter* arb, cpSpace* space, void *data) + { + cpBody* firstBody; + cpBody* secondBody; + cpArbiterGetBodies(arb, &firstBody, &secondBody); + + PhysWorld2D* world = static_cast(cpSpaceGetUserData(space)); + RigidBody2D* firstRigidBody = static_cast(cpBodyGetUserData(firstBody)); + RigidBody2D* secondRigidBody = static_cast(cpBodyGetUserData(secondBody)); + + const Callback* customCallbacks = static_cast(data); + customCallbacks->postSolveCallback(*world, *firstRigidBody, *secondRigidBody, customCallbacks->userdata); + + cpArbiterCallWildcardPostSolveA(arb, space); + cpArbiterCallWildcardPostSolveB(arb, space); + }; + } + } + + void PhysWorld2D::OnRigidBodyMoved(RigidBody2D* oldPointer, RigidBody2D* newPointer) + { + auto it = m_rigidPostSteps.find(oldPointer); + if (it == m_rigidPostSteps.end()) + return; //< Shouldn't happen + + m_rigidPostSteps.emplace(std::make_pair(newPointer, std::move(it->second))); + m_rigidPostSteps.erase(oldPointer); + } + + void PhysWorld2D::OnRigidBodyRelease(RigidBody2D* rigidBody) + { + m_rigidPostSteps.erase(rigidBody); + } + + void PhysWorld2D::RegisterPostStep(RigidBody2D* rigidBody, PostStep&& func) + { + // If space isn't locked, no need to wait + if (!cpSpaceIsLocked(m_handle)) + { + func(rigidBody); + return; + } + + auto it = m_rigidPostSteps.find(rigidBody); + if (it == m_rigidPostSteps.end()) + { + PostStepContainer postStep; + postStep.onMovedSlot.Connect(rigidBody->OnRigidBody2DMove, this, &PhysWorld2D::OnRigidBodyMoved); + postStep.onReleaseSlot.Connect(rigidBody->OnRigidBody2DRelease, this, &PhysWorld2D::OnRigidBodyRelease); + + it = m_rigidPostSteps.insert(std::make_pair(rigidBody, std::move(postStep))).first; + } + + it->second.funcs.emplace_back(std::move(func)); + } } diff --git a/src/Nazara/Physics2D/Physics2D.cpp b/src/Nazara/Physics2D/Physics2D.cpp index 840b14755..f6acdb152 100644 --- a/src/Nazara/Physics2D/Physics2D.cpp +++ b/src/Nazara/Physics2D/Physics2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics2D/RigidBody2D.cpp b/src/Nazara/Physics2D/RigidBody2D.cpp index 9fdb34d50..a19107c2c 100644 --- a/src/Nazara/Physics2D/RigidBody2D.cpp +++ b/src/Nazara/Physics2D/RigidBody2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -20,6 +20,7 @@ namespace Nz RigidBody2D::RigidBody2D(PhysWorld2D* world, float mass, Collider2DRef geom) : m_geom(), + m_userData(nullptr), m_world(world), m_gravityFactor(1.f), m_mass(1.f) @@ -34,6 +35,7 @@ namespace Nz RigidBody2D::RigidBody2D(const RigidBody2D& object) : m_geom(object.m_geom), + m_userData(object.m_userData), m_world(object.m_world), m_gravityFactor(object.m_gravityFactor), m_mass(0.f) @@ -48,18 +50,29 @@ namespace Nz } RigidBody2D::RigidBody2D(RigidBody2D&& object) : + OnRigidBody2DMove(std::move(object.OnRigidBody2DMove)), + OnRigidBody2DRelease(std::move(object.OnRigidBody2DRelease)), m_shapes(std::move(object.m_shapes)), m_geom(std::move(object.m_geom)), + m_userData(object.m_userData), m_handle(object.m_handle), m_world(object.m_world), m_gravityFactor(object.m_gravityFactor), m_mass(object.m_mass) { + cpBodySetUserData(m_handle, this); + for (cpShape* shape : m_shapes) + cpShapeSetUserData(shape, this); + object.m_handle = nullptr; + + OnRigidBody2DMove(&object, this); } RigidBody2D::~RigidBody2D() { + OnRigidBody2DRelease(this); + Destroy(); } @@ -82,6 +95,25 @@ namespace Nz } } + void RigidBody2D::AddImpulse(const Vector2f& impulse, CoordSys coordSys) + { + return AddImpulse(impulse, GetCenterOfGravity(coordSys), coordSys); + } + + void RigidBody2D::AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + cpBodyApplyImpulseAtWorldPoint(m_handle, cpv(impulse.x, impulse.y), cpv(point.x, point.y)); + break; + + case CoordSys_Local: + cpBodyApplyImpulseAtLocalPoint(m_handle, cpv(impulse.x, impulse.y), cpv(point.x, point.y)); + break; + } + } + void RigidBody2D::AddTorque(float torque) { cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + torque); @@ -89,11 +121,15 @@ namespace Nz Rectf RigidBody2D::GetAABB() const { - cpBB bb = cpBBNew(0.f, 0.f, 0.f, 0.f); - for (cpShape* shape : m_shapes) - bb = cpBBMerge(bb, cpShapeGetBB(shape)); + if (m_shapes.empty()) + return Rectf::Zero(); - return Rectf(Rect(bb.l, bb.t, bb.r - bb.l, bb.b - bb.t)); + auto it = m_shapes.begin(); + cpBB bb = cpShapeGetBB(*it++); + for (; it != m_shapes.end(); ++it) + bb = cpBBMerge(bb, cpShapeGetBB(*it)); + + return Rectf(Rect(bb.l, bb.b, bb.r - bb.l, bb.t - bb.b)); } float RigidBody2D::GetAngularVelocity() const @@ -144,6 +180,11 @@ namespace Nz return static_cast(cpBodyGetAngle(m_handle)); } + void* RigidBody2D::GetUserdata() const + { + return m_userData; + } + Vector2f RigidBody2D::GetVelocity() const { cpVect vel = cpBodyGetVelocity(m_handle); @@ -178,7 +219,7 @@ namespace Nz cpVect vel = cpBodyGetVelocity(m_handle); Destroy(); - Create(mass, moment); + Create(float(mass), float(moment)); cpBodySetAngle(m_handle, rot); cpBodySetPosition(m_handle, pos); @@ -190,11 +231,14 @@ namespace Nz else m_geom = NullCollider2D::New(); - m_shapes = m_geom->CreateShapes(this); + m_shapes = m_geom->GenerateShapes(this); cpSpace* space = m_world->GetHandle(); for (cpShape* shape : m_shapes) + { + cpShapeSetUserData(shape, this); cpSpaceAddShape(space, shape); + } cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass)); } @@ -205,20 +249,26 @@ namespace Nz { if (mass > 0.f) { - cpBodySetMass(m_handle, mass); - cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass)); + m_world->RegisterPostStep(this, [mass](Nz::RigidBody2D* body) + { + cpBodySetMass(body->GetHandle(), mass); + cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeInertialMatrix(mass)); + }); } else - cpBodySetType(m_handle, CP_BODY_TYPE_STATIC); + m_world->RegisterPostStep(this, [](Nz::RigidBody2D* body) { cpBodySetType(body->GetHandle(), CP_BODY_TYPE_STATIC); } ); } else if (mass > 0.f) { - if (cpBodyGetType(m_handle) == CP_BODY_TYPE_STATIC) + m_world->RegisterPostStep(this, [mass](Nz::RigidBody2D* body) { - cpBodySetType(m_handle, CP_BODY_TYPE_DYNAMIC); - cpBodySetMass(m_handle, mass); - cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass)); - } + if (cpBodyGetType(body->GetHandle()) == CP_BODY_TYPE_STATIC) + { + cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC); + cpBodySetMass(body->GetHandle(), mass); + cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeInertialMatrix(mass)); + } + }); } m_mass = mass; @@ -242,6 +292,11 @@ namespace Nz cpBodySetAngle(m_handle, rotation); } + void RigidBody2D::SetUserdata(void* ud) + { + m_userData = ud; + } + void RigidBody2D::SetVelocity(const Vector2f& velocity) { cpBodySetVelocity(m_handle, cpv(velocity.x, velocity.y)); @@ -257,15 +312,25 @@ namespace Nz { Destroy(); + OnRigidBody2DMove = std::move(object.OnRigidBody2DMove); + OnRigidBody2DRelease = std::move(object.OnRigidBody2DRelease); + m_handle = object.m_handle; m_geom = std::move(object.m_geom); m_gravityFactor = object.m_gravityFactor; m_mass = object.m_mass; m_shapes = std::move(object.m_shapes); + m_userData = object.m_userData; m_world = object.m_world; + cpBodySetUserData(m_handle, this); + for (cpShape* shape : m_shapes) + cpShapeSetUserData(shape, this); + object.m_handle = nullptr; + OnRigidBody2DMove(&object, this); + return *this; } @@ -273,6 +338,7 @@ namespace Nz { m_handle = cpBodyNew(mass, moment); cpBodySetUserData(m_handle, this); + cpSpaceAddBody(m_world->GetHandle(), m_handle); } diff --git a/src/Nazara/Physics3D/Collider3D.cpp b/src/Nazara/Physics3D/Collider3D.cpp index 7cddffdbe..d71f4caa8 100644 --- a/src/Nazara/Physics3D/Collider3D.cpp +++ b/src/Nazara/Physics3D/Collider3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics3D/Debug/NewOverload.cpp b/src/Nazara/Physics3D/Debug/NewOverload.cpp index b87984066..da675a56f 100644 --- a/src/Nazara/Physics3D/Debug/NewOverload.cpp +++ b/src/Nazara/Physics3D/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics3D/PhysWorld3D.cpp b/src/Nazara/Physics3D/PhysWorld3D.cpp index c6990f635..be2677ef6 100644 --- a/src/Nazara/Physics3D/PhysWorld3D.cpp +++ b/src/Nazara/Physics3D/PhysWorld3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics3D/Physics3D.cpp b/src/Nazara/Physics3D/Physics3D.cpp index 8fb470f2a..033d13374 100644 --- a/src/Nazara/Physics3D/Physics3D.cpp +++ b/src/Nazara/Physics3D/Physics3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics3D/RigidBody3D.cpp b/src/Nazara/Physics3D/RigidBody3D.cpp index 5051fa143..9a909f98f 100644 --- a/src/Nazara/Physics3D/RigidBody3D.cpp +++ b/src/Nazara/Physics3D/RigidBody3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 3D module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Debug/NewOverload.cpp b/src/Nazara/Renderer/Debug/NewOverload.cpp index 6ef952271..1a198d979 100644 --- a/src/Nazara/Renderer/Debug/NewOverload.cpp +++ b/src/Nazara/Renderer/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/HardwareBuffer.cpp b/src/Nazara/Renderer/HardwareBuffer.cpp index d7b5219b4..52bc339c2 100644 --- a/src/Nazara/Renderer/HardwareBuffer.cpp +++ b/src/Nazara/Renderer/HardwareBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/HardwareBuffer.hpp b/src/Nazara/Renderer/HardwareBuffer.hpp index 15a629c8b..d9cb26368 100644 --- a/src/Nazara/Renderer/HardwareBuffer.hpp +++ b/src/Nazara/Renderer/HardwareBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index b90f51903..843e7ae94 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 7df964645..cc7ec3ca8 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/AbstractAtlas.cpp b/src/Nazara/Utility/AbstractAtlas.cpp index 555b0beae..10e4d286f 100644 --- a/src/Nazara/Utility/AbstractAtlas.cpp +++ b/src/Nazara/Utility/AbstractAtlas.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/AbstractBuffer.cpp b/src/Nazara/Utility/AbstractBuffer.cpp index e7bd5ce19..aa550c5a5 100644 --- a/src/Nazara/Utility/AbstractBuffer.cpp +++ b/src/Nazara/Utility/AbstractBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/AbstractImage.cpp b/src/Nazara/Utility/AbstractImage.cpp index adf50d5ae..f539605f1 100644 --- a/src/Nazara/Utility/AbstractImage.cpp +++ b/src/Nazara/Utility/AbstractImage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/AbstractTextDrawer.cpp b/src/Nazara/Utility/AbstractTextDrawer.cpp index c6eb131ae..563c8bf57 100644 --- a/src/Nazara/Utility/AbstractTextDrawer.cpp +++ b/src/Nazara/Utility/AbstractTextDrawer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index 90a3d53e3..d37d02f96 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index a996f85a5..eb53424fe 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 4e589b938..e65488d28 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Cursor.cpp b/src/Nazara/Utility/Cursor.cpp index deddbc753..e8b3e0b21 100644 --- a/src/Nazara/Utility/Cursor.cpp +++ b/src/Nazara/Utility/Cursor.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -16,40 +16,28 @@ namespace Nz { - Cursor::Cursor() : - m_impl(nullptr) - { - } - - Cursor::~Cursor() - { - Destroy(); - } - - bool Cursor::Create(const Image& cursor, int hotSpotX, int hotSpotY) + bool Cursor::Create(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder) { Destroy(); - m_impl = new CursorImpl; - if (!m_impl->Create(cursor, hotSpotX, hotSpotY)) + std::unique_ptr impl(new CursorImpl); + if (!impl->Create(cursor, hotSpot.x, hotSpot.y)) { NazaraError("Failed to create cursor implementation"); - delete m_impl; - m_impl = nullptr; - return false; } + m_cursorImage = cursor; + m_impl = impl.release(); + m_systemCursor = placeholder; + return true; } - bool Cursor::Create(const Image& cursor, const Vector2i& hotSpot) - { - return Create(cursor, hotSpot.x, hotSpot.y); - } - void Cursor::Destroy() { + m_cursorImage.Destroy(); + if (m_impl) { m_impl->Destroy(); @@ -59,8 +47,41 @@ namespace Nz } } - bool Cursor::IsValid() const + bool Cursor::Create(SystemCursor cursor) { - return m_impl != nullptr; + Destroy(); + + std::unique_ptr impl(new CursorImpl); + if (!impl->Create(cursor)) + { + NazaraError("Failed to create cursor implementation"); + return false; + } + + m_impl = impl.release(); + m_systemCursor = cursor; + + return true; } + + bool Cursor::Initialize() + { + if (!CursorImpl::Initialize()) + return false; + + for (std::size_t i = 0; i <= SystemCursor_Max; ++i) + s_systemCursors[i].Create(static_cast(i)); + + return true; + } + + void Cursor::Uninitialize() + { + for (Cursor& cursor : s_systemCursors) + cursor.Destroy(); + + CursorImpl::Uninitialize(); + } + + std::array Cursor::s_systemCursors; } diff --git a/src/Nazara/Utility/Debug/NewOverload.cpp b/src/Nazara/Utility/Debug/NewOverload.cpp index 00dc7f90c..18bca9315 100644 --- a/src/Nazara/Utility/Debug/NewOverload.cpp +++ b/src/Nazara/Utility/Debug/NewOverload.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index b5914aa58..63cc28495 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/FontData.cpp b/src/Nazara/Utility/FontData.cpp index b9be6b8e7..00480ec9f 100644 --- a/src/Nazara/Utility/FontData.cpp +++ b/src/Nazara/Utility/FontData.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/DDSConstants.cpp b/src/Nazara/Utility/Formats/DDSConstants.cpp index 3c078475f..0fda7ac16 100644 --- a/src/Nazara/Utility/Formats/DDSConstants.cpp +++ b/src/Nazara/Utility/Formats/DDSConstants.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index 1e707e610..ad2ff9969 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq - 2009 Cruden BV +// Copyright (C) 2017 Jérôme Leclercq - 2009 Cruden BV // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/Formats/DDSLoader.hpp b/src/Nazara/Utility/Formats/DDSLoader.hpp index 8027d1356..dd524fd04 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.hpp +++ b/src/Nazara/Utility/Formats/DDSLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index aed76d608..f6ab78b1d 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq - 2009 Cruden BV +// Copyright (C) 2017 Jérôme Leclercq - 2009 Cruden BV // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.hpp b/src/Nazara/Utility/Formats/FreeTypeLoader.hpp index a88e2adae..f7775fca5 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.hpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD2Constants.cpp b/src/Nazara/Utility/Formats/MD2Constants.cpp index f80cb0b2c..f381689ec 100644 --- a/src/Nazara/Utility/Formats/MD2Constants.cpp +++ b/src/Nazara/Utility/Formats/MD2Constants.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD2Constants.hpp b/src/Nazara/Utility/Formats/MD2Constants.hpp index 694f15dae..deb16757d 100644 --- a/src/Nazara/Utility/Formats/MD2Constants.hpp +++ b/src/Nazara/Utility/Formats/MD2Constants.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index c28a12de0..76ee1c1ea 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD2Loader.hpp b/src/Nazara/Utility/Formats/MD2Loader.hpp index 3fdafd4d0..98a405600 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.hpp +++ b/src/Nazara/Utility/Formats/MD2Loader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index e263ceef3..026c9e5d7 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.hpp b/src/Nazara/Utility/Formats/MD5AnimLoader.hpp index b1691ee6b..610d0d53f 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.hpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD5AnimParser.cpp b/src/Nazara/Utility/Formats/MD5AnimParser.cpp index a1b02153b..5930fe5a3 100644 --- a/src/Nazara/Utility/Formats/MD5AnimParser.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimParser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 26aef0a1f..5284d1d2c 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -91,8 +91,8 @@ namespace Nz bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage, 0); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, UInt32(indexCount), parameters.storage, 0); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), UInt32(vertexCount), parameters.storage, 0); // Index buffer IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); @@ -236,7 +236,7 @@ namespace Nz // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, UInt32(indexCount), parameters.storage, 0); IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); IndexIterator index = indexMapper.begin(); @@ -251,7 +251,7 @@ namespace Nz indexMapper.Unmap(); // Vertex buffer - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, 0); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), UInt32(vertexCount), parameters.storage, 0); BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); MeshVertex* vertices = static_cast(vertexMapper.GetPointer()); diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.hpp b/src/Nazara/Utility/Formats/MD5MeshLoader.hpp index 02b63d0ff..b59d57998 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.hpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index ce5264d01..470e9a41a 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/MTLParser.cpp b/src/Nazara/Utility/Formats/MTLParser.cpp index c3b60a6e5..894f20f02 100644 --- a/src/Nazara/Utility/Formats/MTLParser.cpp +++ b/src/Nazara/Utility/Formats/MTLParser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 2371e18fd..d7dd15d14 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -124,8 +124,8 @@ namespace Nz // Some default settings data.SetParameter(MaterialData::Blending, true); data.SetParameter(MaterialData::DepthWrite, true); - data.SetParameter(MaterialData::DstBlend, static_cast(BlendFunc_InvSrcAlpha)); - data.SetParameter(MaterialData::SrcBlend, static_cast(BlendFunc_SrcAlpha)); + data.SetParameter(MaterialData::DstBlend, static_cast(BlendFunc_InvSrcAlpha)); + data.SetParameter(MaterialData::SrcBlend, static_cast(BlendFunc_SrcAlpha)); } it = materialCache.emplace(matName, std::move(data)).first; @@ -139,7 +139,7 @@ namespace Nz bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { - int reservedVertexCount; + long long reservedVertexCount; if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount)) reservedVertexCount = 100; @@ -233,8 +233,8 @@ namespace Nz } // Création des buffers - IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.storage, 0); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, 0); + IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), UInt32(indices.size()), parameters.storage, 0); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), UInt32(vertexCount), parameters.storage, 0); // Remplissage des indices IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); diff --git a/src/Nazara/Utility/Formats/OBJLoader.hpp b/src/Nazara/Utility/Formats/OBJLoader.hpp index 46dd8d976..dbbeaa6bc 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.hpp +++ b/src/Nazara/Utility/Formats/OBJLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index eed0ee2b1..f85251f57 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -228,7 +228,7 @@ namespace Nz if (p < 0) { - p += m_positions.size() - 1; + p += static_cast(m_positions.size() - 1); if (p < 0) { Error("Vertex index out of range (" + String::Number(p) + " < 0"); @@ -239,7 +239,7 @@ namespace Nz if (n < 0) { - n += m_normals.size() - 1; + n += static_cast(m_normals.size() - 1); if (n < 0) { Error("Normal index out of range (" + String::Number(n) + " < 0"); @@ -250,7 +250,7 @@ namespace Nz if (t < 0) { - t += m_texCoords.size() - 1; + t += static_cast(m_texCoords.size() - 1); if (t < 0) { Error("Texture coordinates index out of range (" + String::Number(t) + " < 0"); diff --git a/src/Nazara/Utility/Formats/OBJSaver.cpp b/src/Nazara/Utility/Formats/OBJSaver.cpp index 761432473..7b3507730 100644 --- a/src/Nazara/Utility/Formats/OBJSaver.cpp +++ b/src/Nazara/Utility/Formats/OBJSaver.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -128,7 +128,7 @@ namespace Nz else { Color colorVal; - float fValue; + double dValue; if (matData.GetColorParameter(MaterialData::AmbientColor, &colorVal)) material->ambient = colorVal; @@ -139,8 +139,8 @@ namespace Nz if (matData.GetColorParameter(MaterialData::SpecularColor, &colorVal)) material->specular = colorVal; - if (matData.GetFloatParameter(MaterialData::Shininess, &fValue)) - material->shininess = fValue; + if (matData.GetDoubleParameter(MaterialData::Shininess, &dValue)) + material->shininess = float(dValue); if (matData.GetStringParameter(MaterialData::AlphaTexturePath, &strVal)) material->alphaMap = strVal; @@ -176,7 +176,7 @@ namespace Nz UInt32 faceIndex = 0; TriangleIterator triangle(staticMesh); - do + do { OBJParser::Face& face = meshes[i].faces[faceIndex]; face.firstVertex = faceIndex * 3; diff --git a/src/Nazara/Utility/Formats/OBJSaver.hpp b/src/Nazara/Utility/Formats/OBJSaver.hpp index ed909f165..3647a317c 100644 --- a/src/Nazara/Utility/Formats/OBJSaver.hpp +++ b/src/Nazara/Utility/Formats/OBJSaver.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/Formats/PCXLoader.cpp b/src/Nazara/Utility/Formats/PCXLoader.cpp index 1dc7622bd..bb0e1b43b 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.cpp +++ b/src/Nazara/Utility/Formats/PCXLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/PCXLoader.hpp b/src/Nazara/Utility/Formats/PCXLoader.hpp index 6ef8d86c1..be3574026 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.hpp +++ b/src/Nazara/Utility/Formats/PCXLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 3ca5b3708..83b9880dd 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/STBLoader.hpp b/src/Nazara/Utility/Formats/STBLoader.hpp index 03e08c72f..4b94f84e9 100644 --- a/src/Nazara/Utility/Formats/STBLoader.hpp +++ b/src/Nazara/Utility/Formats/STBLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/STBSaver.cpp b/src/Nazara/Utility/Formats/STBSaver.cpp index 26c6067fe..0e2f31e3f 100644 --- a/src/Nazara/Utility/Formats/STBSaver.cpp +++ b/src/Nazara/Utility/Formats/STBSaver.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Formats/STBSaver.hpp b/src/Nazara/Utility/Formats/STBSaver.hpp index 9a511c07e..e1bbbe3e1 100644 --- a/src/Nazara/Utility/Formats/STBSaver.hpp +++ b/src/Nazara/Utility/Formats/STBSaver.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index b3e630921..74cff70db 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Icon.cpp b/src/Nazara/Utility/Icon.cpp index 0fa4fba11..843e64456 100644 --- a/src/Nazara/Utility/Icon.cpp +++ b/src/Nazara/Utility/Icon.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -16,30 +16,19 @@ namespace Nz { - Icon::Icon() : - m_impl(nullptr) - { - } - - Icon::~Icon() - { - Destroy(); - } - bool Icon::Create(const Image& icon) { Destroy(); - m_impl = new IconImpl; - if (!m_impl->Create(icon)) + std::unique_ptr impl(new IconImpl); + if (!impl->Create(icon)) { NazaraError("Failed to create icon implementation"); - delete m_impl; - m_impl = nullptr; - return false; } + m_impl = impl.release(); + return true; } @@ -53,9 +42,4 @@ namespace Nz m_impl = nullptr; } } - - bool Icon::IsValid() const - { - return m_impl != nullptr; - } } diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 39d99cdd1..15d9133fe 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -835,7 +835,6 @@ namespace Nz if (!PixelFormat::IsCompressed(m_sharedImage->format)) { const PixelFormatInfo& info = PixelFormat::GetInfo(m_sharedImage->format); - const UInt8* pixel = GetConstPixels(); Bitset<> workingBitset; std::size_t pixelCount = m_sharedImage->width * m_sharedImage->height * ((m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth); diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 90090aabe..306fffb7f 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -35,10 +35,10 @@ namespace Nz IndexBuffer::IndexBuffer(const IndexBuffer& indexBuffer) : RefCounted(), m_buffer(indexBuffer.m_buffer), - m_largeIndices(indexBuffer.m_largeIndices), m_endOffset(indexBuffer.m_endOffset), m_indexCount(indexBuffer.m_indexCount), - m_startOffset(indexBuffer.m_startOffset) + m_startOffset(indexBuffer.m_startOffset), + m_largeIndices(indexBuffer.m_largeIndices) { } diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index 5a664128c..78fdd36a0 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -12,38 +12,38 @@ namespace Nz { namespace { - UInt32 GetterSequential(const void* buffer, unsigned int i) + UInt32 GetterSequential(const void* buffer, std::size_t i) { NazaraUnused(buffer); - return i; + return static_cast(i); } - UInt32 Getter16(const void* buffer, unsigned int i) + UInt32 Getter16(const void* buffer, std::size_t i) { const UInt16* ptr = static_cast(buffer); return ptr[i]; } - UInt32 Getter32(const void* buffer, unsigned int i) + UInt32 Getter32(const void* buffer, std::size_t i) { const UInt32* ptr = static_cast(buffer); return ptr[i]; } - void Setter16(void* buffer, unsigned int i, UInt32 value) + void Setter16(void* buffer, std::size_t i, UInt32 value) { UInt16* ptr = static_cast(buffer); ptr[i] = static_cast(value); } - void Setter32(void* buffer, unsigned int i, UInt32 value) + void Setter32(void* buffer, std::size_t i, UInt32 value) { UInt32* ptr = static_cast(buffer); ptr[i] = value; } - void SetterError(void*, unsigned int, UInt32) + void SetterError(void*, std::size_t, UInt32) { NazaraError("Index buffer opened with read-only access"); } @@ -113,15 +113,9 @@ namespace Nz { } - UInt32 IndexMapper::Get(unsigned int i) const + UInt32 IndexMapper::Get(std::size_t i) const { - #if NAZARA_UTILITY_SAFE - if (i >= m_indexCount) - { - NazaraError("Index out of range (" + String::Number(i) + " >= " + String::Number(m_indexCount) + ')'); - return 0; - } - #endif + NazaraAssert(i < m_indexCount, "Index out of range"); return m_getter(m_mapper.GetPointer(), i); } @@ -131,20 +125,14 @@ namespace Nz return m_mapper.GetBuffer(); } - unsigned int IndexMapper::GetIndexCount() const + std::size_t IndexMapper::GetIndexCount() const { return m_indexCount; } - void IndexMapper::Set(unsigned int i, UInt32 value) + void IndexMapper::Set(std::size_t i, UInt32 value) { - #if NAZARA_UTILITY_SAFE - if (i >= m_indexCount) - { - NazaraError("Index out of range (" + String::Number(i) + " >= " + String::Number(m_indexCount) + ')'); - return; - } - #endif + NazaraAssert(i < m_indexCount, "Index out of range"); m_setter(m_mapper.GetPointer(), i, value); } diff --git a/src/Nazara/Utility/Joint.cpp b/src/Nazara/Utility/Joint.cpp index 4bd040faa..5d3a3796c 100644 --- a/src/Nazara/Utility/Joint.cpp +++ b/src/Nazara/Utility/Joint.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Keyboard.cpp b/src/Nazara/Utility/Keyboard.cpp index fb0bb05a5..08f4b05a7 100644 --- a/src/Nazara/Utility/Keyboard.cpp +++ b/src/Nazara/Utility/Keyboard.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 32db98e24..b6985714e 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -79,7 +79,7 @@ namespace Nz NazaraAssert(subMesh, "Invalid submesh"); NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type"); - m_impl->subMeshes.push_back(subMesh); + m_impl->subMeshes.emplace_back(subMesh); InvalidateAABB(); } @@ -92,10 +92,10 @@ namespace Nz NazaraAssert(subMesh, "Invalid submesh"); NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type"); - UInt32 index = m_impl->subMeshes.size(); + std::size_t index = m_impl->subMeshes.size(); - m_impl->subMeshes.push_back(subMesh); - m_impl->subMeshMap[identifier] = index; + m_impl->subMeshes.emplace_back(subMesh); + m_impl->subMeshMap[identifier] = static_cast(index); InvalidateAABB(); } @@ -349,11 +349,11 @@ namespace Nz if (!m_impl->aabbUpdated) { - UInt32 subMeshCount = m_impl->subMeshes.size(); + std::size_t subMeshCount = m_impl->subMeshes.size(); if (subMeshCount > 0) { m_impl->aabb.Set(m_impl->subMeshes[0]->GetAABB()); - for (UInt32 i = 1; i < subMeshCount; ++i) + for (std::size_t i = 1; i < subMeshCount; ++i) m_impl->aabb.ExtendTo(m_impl->subMeshes[i]->GetAABB()); } else @@ -407,7 +407,7 @@ namespace Nz { NazaraAssert(m_impl, "Mesh should be created first"); - return m_impl->materialData.size(); + return static_cast(m_impl->materialData.size()); } Skeleton* Mesh::GetSkeleton() @@ -466,7 +466,7 @@ namespace Nz { NazaraAssert(m_impl, "Mesh should be created first"); - return m_impl->subMeshes.size(); + return static_cast(m_impl->subMeshes.size()); } UInt32 Mesh::GetSubMeshIndex(const String& identifier) const diff --git a/src/Nazara/Utility/Mouse.cpp b/src/Nazara/Utility/Mouse.cpp index 24cec91f7..b25ce2506 100644 --- a/src/Nazara/Utility/Mouse.cpp +++ b/src/Nazara/Utility/Mouse.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index 8754ab320..2832df42d 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index 77f6bdbb2..f27f6bd00 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -1268,6 +1268,102 @@ namespace Nz } } + bool PixelFormat::Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst) + { + #if NAZARA_UTILITY_SAFE + if (!IsValid(format)) + { + NazaraError("Invalid pixel format"); + return false; + } + #endif + + auto it = s_flipFunctions[flipping].find(format); + if (it != s_flipFunctions[flipping].end()) + it->second(width, height, depth, reinterpret_cast(src), reinterpret_cast(dst)); + else + { + // Flipping générique + + #if NAZARA_UTILITY_SAFE + if (IsCompressed(format)) + { + NazaraError("No function to flip compressed format"); + return false; + } + #endif + + UInt8 bpp = GetBytesPerPixel(format); + unsigned int lineStride = width*bpp; + switch (flipping) + { + case PixelFlipping_Horizontally: + { + if (src == dst) + { + for (unsigned int z = 0; z < depth; ++z) + { + UInt8* ptr = reinterpret_cast(dst) + width*height*z; + for (unsigned int y = 0; y < height / 2; ++y) + std::swap_ranges(&ptr[y*lineStride], &ptr[(y + 1)*lineStride - 1], &ptr[(height - y - 1)*lineStride]); + } + } + else + { + for (unsigned int z = 0; z < depth; ++z) + { + const UInt8* srcPtr = reinterpret_cast(src); + UInt8* dstPtr = reinterpret_cast(dst) + (width - 1)*height*depth*bpp; + for (unsigned int y = 0; y < height; ++y) + { + std::memcpy(dstPtr, srcPtr, lineStride); + + srcPtr += lineStride; + dstPtr -= lineStride; + } + } + } + break; + } + + case PixelFlipping_Vertically: + { + if (src == dst) + { + for (unsigned int z = 0; z < depth; ++z) + { + UInt8* ptr = reinterpret_cast(dst) + width*height*z; + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width / 2; ++x) + std::swap_ranges(&ptr[x*bpp], &ptr[(x + 1)*bpp], &ptr[(width - x)*bpp]); + + ptr += lineStride; + } + } + } + else + { + for (unsigned int z = 0; z < depth; ++z) + { + UInt8* ptr = reinterpret_cast(dst) + width*height*z; + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + std::memcpy(&ptr[x*bpp], &ptr[(width - x)*bpp], bpp); + + ptr += lineStride; + } + } + } + break; + } + } + } + + return true; + } + PixelFormatType PixelFormat::IdentifyFormat(const PixelFormatInfo& info) { for (unsigned int i = 0; i <= PixelFormatType_Max; ++i) diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index cdf6f8ceb..1b53f808f 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -243,7 +243,7 @@ namespace Nz m_workingBounds.MakeZero(); //< Compute bounds as float to speedup bounds computation (as casting between floats and integers is costly) if (m_font) - m_lines.emplace_back(Line{Rectf(0.f, 0.f, 0.f, m_font->GetSizeInfo(m_characterSize).lineHeight), 0}); + m_lines.emplace_back(Line{Rectf(0.f, 0.f, 0.f, float(m_font->GetSizeInfo(m_characterSize).lineHeight)), 0}); else m_lines.emplace_back(Line{Rectf::Zero(), 0}); } @@ -354,7 +354,7 @@ namespace Nz { glyph.atlas = nullptr; - glyph.bounds.Set(m_drawPos.x, m_drawPos.y, float(advance), sizeInfo.lineHeight); + glyph.bounds.Set(float(m_drawPos.x), float(m_drawPos.y), float(advance), float(sizeInfo.lineHeight)); glyph.corners[0].Set(glyph.bounds.GetCorner(RectCorner_LeftTop)); glyph.corners[1].Set(glyph.bounds.GetCorner(RectCorner_RightTop)); @@ -365,17 +365,19 @@ namespace Nz { case '\n': { + // Extend the line bounding rect to the last glyph it contains, thus extending upon all glyphs of the line if (!m_glyphs.empty()) { - Glyph& glyph = m_glyphs.back(); - m_lines.back().bounds.ExtendTo(glyph.bounds); + Glyph& lastGlyph = m_glyphs.back(); + m_lines.back().bounds.ExtendTo(lastGlyph.bounds); } + // Reset cursor advance = 0; m_drawPos.x = 0; m_drawPos.y += sizeInfo.lineHeight; - m_lines.emplace_back(Line{Rectf(0.f, sizeInfo.lineHeight * m_lines.size(), 0.f, sizeInfo.lineHeight), m_glyphs.size() + 1}); + m_lines.emplace_back(Line{Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1}); break; } } diff --git a/src/Nazara/Utility/SkeletalMesh.cpp b/src/Nazara/Utility/SkeletalMesh.cpp index 0f81ac189..e866c0d33 100644 --- a/src/Nazara/Utility/SkeletalMesh.cpp +++ b/src/Nazara/Utility/SkeletalMesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Skeleton.cpp b/src/Nazara/Utility/Skeleton.cpp index 70f7adb07..480522b4e 100644 --- a/src/Nazara/Utility/Skeleton.cpp +++ b/src/Nazara/Utility/Skeleton.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -72,12 +72,12 @@ namespace Nz if (!m_impl->aabbUpdated) { - UInt32 jointCount = m_impl->joints.size(); + std::size_t jointCount = m_impl->joints.size(); if (jointCount > 0) { Vector3f pos = m_impl->joints[0].GetPosition(); m_impl->aabb.Set(pos.x, pos.y, pos.z, 0.f, 0.f, 0.f); - for (UInt32 i = 1; i < jointCount; ++i) + for (std::size_t i = 1; i < jointCount; ++i) m_impl->aabb.ExtendTo(m_impl->joints[i].GetPosition()); } else @@ -219,7 +219,7 @@ namespace Nz } #endif - return m_impl->joints.size(); + return static_cast(m_impl->joints.size()); } int Skeleton::GetJointIndex(const String& jointName) const @@ -411,16 +411,9 @@ namespace Nz String name = m_impl->joints[i].GetName(); if (!name.IsEmpty()) { - #if NAZARA_UTILITY_SAFE - auto it = m_impl->jointMap.find(name); - if (it != m_impl->jointMap.end()) - { - NazaraWarning("Joint name \"" + name + "\" is already present in joint map for joint #" + String::Number(it->second)); - continue; - } - #endif + NazaraAssert(m_impl->jointMap.find(name) == m_impl->jointMap.end(), "Joint name \"" + name + "\" is already present in joint map"); - m_impl->jointMap[name] = i; + m_impl->jointMap[name] = static_cast(i); } } diff --git a/src/Nazara/Utility/SoftwareBuffer.cpp b/src/Nazara/Utility/SoftwareBuffer.cpp index 2f69e02ac..6dce1fc6a 100644 --- a/src/Nazara/Utility/SoftwareBuffer.cpp +++ b/src/Nazara/Utility/SoftwareBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/StaticMesh.cpp b/src/Nazara/Utility/StaticMesh.cpp index 6c6056864..a1a25f3d7 100644 --- a/src/Nazara/Utility/StaticMesh.cpp +++ b/src/Nazara/Utility/StaticMesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index c8da223f0..9607052fb 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/TriangleIterator.cpp b/src/Nazara/Utility/TriangleIterator.cpp index 53086ddb8..ad6dfb2c6 100644 --- a/src/Nazara/Utility/TriangleIterator.cpp +++ b/src/Nazara/Utility/TriangleIterator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -66,18 +66,9 @@ namespace Nz return true; } - UInt32 TriangleIterator::operator[](unsigned int i) const + UInt32 TriangleIterator::operator[](std::size_t i) const { - #if NAZARA_UTILITY_SAFE - if (i >= 3) - { - StringStream ss; - ss << "Index out of range: (" << i << " >= 3)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); - } - #endif + NazaraAssert(i < 3, "Index out of range"); return m_triangleIndices[i]; } diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index 87b154157..c6e87e0bb 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,13 @@ namespace Nz NazaraError("Failed to initialize window's system"); return false; } + + // Must be initialized after Window + if (!Cursor::Initialize()) + { + NazaraError("Failed to initialize cursors"); + return false; + } } // On enregistre les loaders pour les extensions @@ -180,7 +188,9 @@ namespace Nz Loaders::UnregisterSTBLoader(); Loaders::UnregisterSTBSaver(); + Cursor::Uninitialize(); //< Must be done before Window Window::Uninitialize(); + VertexDeclaration::Uninitialize(); Skeleton::Uninitialize(); PixelFormat::Uninitialize(); diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index bd3073427..f06d46ed0 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -31,10 +31,10 @@ namespace Nz VertexBuffer::VertexBuffer(const VertexBuffer& vertexBuffer) : RefCounted(), m_buffer(vertexBuffer.m_buffer), - m_vertexDeclaration(vertexBuffer.m_vertexDeclaration), m_endOffset(vertexBuffer.m_endOffset), m_startOffset(vertexBuffer.m_startOffset), - m_vertexCount(vertexBuffer.m_vertexCount) + m_vertexCount(vertexBuffer.m_vertexCount), + m_vertexDeclaration(vertexBuffer.m_vertexDeclaration) { } diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 945888406..51160ab3f 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/VertexMapper.cpp b/src/Nazara/Utility/VertexMapper.cpp index 158dae801..43a96a89a 100644 --- a/src/Nazara/Utility/VertexMapper.cpp +++ b/src/Nazara/Utility/VertexMapper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/VideoMode.cpp b/src/Nazara/Utility/VideoMode.cpp index 2c6a2f321..7d1f3beec 100644 --- a/src/Nazara/Utility/VideoMode.cpp +++ b/src/Nazara/Utility/VideoMode.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/VideoModeImpl.hpp b/src/Nazara/Utility/VideoModeImpl.hpp index 7baeb6478..e5c5c0118 100644 --- a/src/Nazara/Utility/VideoModeImpl.hpp +++ b/src/Nazara/Utility/VideoModeImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/CursorImpl.cpp b/src/Nazara/Utility/Win32/CursorImpl.cpp index eec8785bb..c2fff0a40 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.cpp +++ b/src/Nazara/Utility/Win32/CursorImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -30,27 +30,77 @@ namespace Nz iconInfo.hbmMask = monoBitmap; iconInfo.hbmColor = bitmap; - m_cursor = CreateIconIndirect(&iconInfo); + m_icon = CreateIconIndirect(&iconInfo); DeleteObject(bitmap); DeleteObject(monoBitmap); - if (!m_cursor) + if (!m_icon) { NazaraError("Failed to create cursor: " + Error::GetLastSystemError()); return false; } + m_cursor = m_icon; + + return true; + } + + bool CursorImpl::Create(SystemCursor cursor) + { + if (cursor != SystemCursor_Move) + m_cursor = static_cast(LoadImage(nullptr, s_systemCursorIds[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED)); + else + m_cursor = nullptr; + + // No need to free the cursor if shared + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx + m_icon = nullptr; + return true; } void CursorImpl::Destroy() { - DestroyIcon(m_cursor); + if (m_icon) + DestroyIcon(m_icon); } HCURSOR CursorImpl::GetCursor() { return m_cursor; } + + bool CursorImpl::Initialize() + { + return true; + } + + void CursorImpl::Uninitialize() + { + } + + std::array CursorImpl::s_systemCursorIds = + { + IDC_CROSS, // SystemCursor_Crosshair + IDC_ARROW, // SystemCursor_Default + IDC_HAND, // SystemCursor_Hand + IDC_HELP, // SystemCursor_Help + IDC_SIZEALL, // SystemCursor_Move + nullptr, // SystemCursor_None + IDC_HAND, // SystemCursor_Pointer + IDC_APPSTARTING, // SystemCursor_Progress + IDC_SIZEWE, // SystemCursor_ResizeE + IDC_SIZENS, // SystemCursor_ResizeN + IDC_SIZENESW, // SystemCursor_ResizeNE + IDC_SIZENWSE, // SystemCursor_ResizeNW + IDC_SIZENS, // SystemCursor_ResizeS + IDC_SIZENWSE, // SystemCursor_ResizeSE + IDC_SIZENESW, // SystemCursor_ResizeSW + IDC_SIZEWE, // SystemCursor_ResizeW + IDC_IBEAM, // SystemCursor_Text + IDC_WAIT // SystemCursor_Wait + }; + + static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete"); } diff --git a/src/Nazara/Utility/Win32/CursorImpl.hpp b/src/Nazara/Utility/Win32/CursorImpl.hpp index 78662228e..a8f82377c 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.hpp +++ b/src/Nazara/Utility/Win32/CursorImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -8,6 +8,8 @@ #define NAZARA_CURSORIMPL_HPP #include +#include +#include #include namespace Nz @@ -16,14 +18,24 @@ namespace Nz class CursorImpl { + friend class Cursor; + public: bool Create(const Image& image, int hotSpotX, int hotSpotY); + bool Create(SystemCursor cursor); + void Destroy(); HCURSOR GetCursor(); private: - HICON m_cursor = nullptr; + static bool Initialize(); + static void Uninitialize(); + + HCURSOR m_cursor = nullptr; + HICON m_icon = nullptr; + + static std::array s_systemCursorIds; }; } diff --git a/src/Nazara/Utility/Win32/IconImpl.cpp b/src/Nazara/Utility/Win32/IconImpl.cpp index 0fdbe087b..19e7fffb0 100644 --- a/src/Nazara/Utility/Win32/IconImpl.cpp +++ b/src/Nazara/Utility/Win32/IconImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/IconImpl.hpp b/src/Nazara/Utility/Win32/IconImpl.hpp index d3539d9f3..7ba9acc7a 100644 --- a/src/Nazara/Utility/Win32/IconImpl.hpp +++ b/src/Nazara/Utility/Win32/IconImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Utility/Win32/InputImpl.cpp index ba604deb8..e250ae8be 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Utility/Win32/InputImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/InputImpl.hpp b/src/Nazara/Utility/Win32/InputImpl.hpp index b2a0a9302..e91bfd889 100644 --- a/src/Nazara/Utility/Win32/InputImpl.hpp +++ b/src/Nazara/Utility/Win32/InputImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.cpp b/src/Nazara/Utility/Win32/VideoModeImpl.cpp index ab9fe3430..95a964790 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.cpp +++ b/src/Nazara/Utility/Win32/VideoModeImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.hpp b/src/Nazara/Utility/Win32/VideoModeImpl.hpp index 722553305..460cec364 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.hpp +++ b/src/Nazara/Utility/Win32/VideoModeImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index e32caf95f..c9e94876e 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -1,11 +1,9 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 // Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation -#define OEMRESOURCE - #include #include #include @@ -38,30 +36,6 @@ namespace Nz { namespace { - LPTSTR windowsCursors[] = - { - IDC_CROSS, // WindowCursor_Crosshair - IDC_ARROW, // WindowCursor_Default - IDC_HAND, // WindowCursor_Hand - IDC_HAND, // WindowCursor_Pointer - IDC_HELP, // WindowCursor_Help - IDC_SIZEALL, // WindowCursor_Move - nullptr, // WindowCursor_None - IDC_APPSTARTING, // WindowCursor_Progress - IDC_SIZENS, // WindowCursor_ResizeN - IDC_SIZENS, // WindowCursor_ResizeS - IDC_SIZENWSE, // WindowCursor_ResizeNW - IDC_SIZENWSE, // WindowCursor_ResizeSE - IDC_SIZENESW, // WindowCursor_ResizeNE - IDC_SIZENESW, // WindowCursor_ResizeSW - IDC_SIZEWE, // WindowCursor_ResizeE - IDC_SIZEWE, // WindowCursor_ResizeW - IDC_IBEAM, // WindowCursor_Text - IDC_WAIT // WindowCursor_Wait - }; - - static_assert(sizeof(windowsCursors)/sizeof(LPTSTR) == WindowCursor_Max+1, "Cursor type array is incomplete"); - const wchar_t* className = L"Nazara Window"; WindowImpl* fullscreenWindow = nullptr; } @@ -321,26 +295,6 @@ namespace Nz } } - void WindowImpl::SetCursor(WindowCursor cursor) - { - #ifdef NAZARA_DEBUG - if (cursor > WindowCursor_Max) - { - NazaraError("Window cursor out of enum"); - return; - } - #endif - - if (cursor != WindowCursor_None) - m_cursor = static_cast(LoadImage(nullptr, windowsCursors[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED)); - else - m_cursor = nullptr; - - // Pas besoin de libérer le curseur par la suite s'il est partagé - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx - ::SetCursor(m_cursor); - } - void WindowImpl::SetCursor(const Cursor& cursor) { m_cursor = cursor.m_impl->GetCursor(); diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp index ae08e42ad..83056f825 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Utility/Win32/WindowImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -27,7 +27,7 @@ namespace Nz class Mutex; class Window; - #undef IsMinimized // Conflit avec la méthode du même nom + #undef IsMinimized // Conflits with windows.h redefinition class WindowImpl { @@ -62,7 +62,6 @@ namespace Nz void ProcessEvents(bool block); - void SetCursor(WindowCursor cursor); void SetCursor(const Cursor& cursor); void SetEventListener(bool listener); void SetFocus(); diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index 73c91168a..3130c6641 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 @@ -29,6 +29,20 @@ namespace Nz Window* fullscreenWindow = nullptr; } + Window::Window() : + m_impl(nullptr), + m_asyncWindow(false), + m_closeOnQuit(true), + m_eventPolling(false), + m_waitForEvent(false) + { + m_cursorController.OnCursorUpdated.Connect([this](const CursorController*, const CursorRef& cursor) + { + if (IsValid()) + SetCursor(cursor); + }); + } + Window::~Window() { Destroy(); @@ -90,11 +104,12 @@ namespace Nz // Paramètres par défaut m_impl->EnableKeyRepeat(true); m_impl->EnableSmoothScrolling(false); - m_impl->SetCursor(WindowCursor_Default); m_impl->SetMaximumSize(-1, -1); m_impl->SetMinimumSize(-1, -1); m_impl->SetVisible(true); + SetCursor(Cursor::Get(SystemCursor_Default)); + if (opened) m_impl->SetPosition(position.x, position.y); @@ -137,6 +152,8 @@ namespace Nz void Window::Destroy() { + m_cursor.Reset(); + if (m_impl) { OnWindowDestroy(); @@ -350,36 +367,13 @@ namespace Nz } } - void Window::SetCursor(WindowCursor cursor) + void Window::SetCursor(CursorRef cursor) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif + NazaraAssert(m_impl, "Window not created"); + NazaraAssert(cursor && cursor->IsValid(), "Invalid cursor"); - m_impl->SetCursor(cursor); - } - - void Window::SetCursor(const Cursor& cursor) - { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - - if (!cursor.IsValid()) - { - NazaraError("Cursor is not valid"); - return; - } - #endif - - m_impl->SetCursor(cursor); + m_cursor = std::move(cursor); + m_impl->SetCursor(*m_cursor); } void Window::SetEventListener(bool listener) @@ -414,23 +408,13 @@ namespace Nz m_impl->SetFocus(); } - void Window::SetIcon(const Icon& icon) + void Window::SetIcon(IconRef icon) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } + NazaraAssert(m_impl, "Window not created"); + NazaraAssert(icon && icon.IsValid(), "Invalid icon"); - if (!icon.IsValid()) - { - NazaraError("Icon is not valid"); - return; - } - #endif - - m_impl->SetIcon(icon); + m_icon = std::move(icon); + m_impl->SetIcon(*m_icon); } void Window::SetMaximumSize(const Vector2i& maxSize) diff --git a/src/Nazara/Utility/X11/CursorImpl.cpp b/src/Nazara/Utility/X11/CursorImpl.cpp index d09f51a1f..aa59290b3 100644 --- a/src/Nazara/Utility/X11/CursorImpl.cpp +++ b/src/Nazara/Utility/X11/CursorImpl.cpp @@ -159,16 +159,112 @@ namespace Nz return true; } + bool CursorImpl::Create(SystemCursor cursor) + { + ScopedXCBConnection connection; + xcb_screen_t* screen = X11::XCBDefaultScreen(connection); + + const char* cursorName = s_systemCursorIds[cursor]; + if (cursorName) + { + if (xcb_cursor_context_new(connection, screen, &m_cursorContext) >= 0) + m_cursor = xcb_cursor_load_cursor(m_cursorContext, cursorName); + else + { + NazaraError("Failed to create cursor context"); + return false; + } + } + else + m_cursor = s_hiddenCursor; + + return true; + } + void CursorImpl::Destroy() { ScopedXCBConnection connection; xcb_free_cursor(connection, m_cursor); - m_cursor = 0; + if (m_cursorContext) + xcb_cursor_context_free(m_cursorContext); } xcb_cursor_t CursorImpl::GetCursor() { return m_cursor; } + + bool CursorImpl::Initialize() + { + ScopedXCBConnection connection; + XCBPixmap cursorPixmap(connection); + + xcb_window_t window = X11::XCBDefaultRootWindow(connection); + + if (!cursorPixmap.Create(1, window, 1, 1)) + { + NazaraError("Failed to create pixmap for hidden cursor"); + return false; + } + + s_hiddenCursor = xcb_generate_id(connection); + + // Create the cursor, using the pixmap as both the shape and the mask of the cursor + if (!X11::CheckCookie( + connection, xcb_create_cursor(connection, + s_hiddenCursor, + cursorPixmap, + cursorPixmap, + 0, 0, 0, // Foreground RGB color + 0, 0, 0, // Background RGB color + 0, // X + 0 // Y + ))) + { + NazaraError("Failed to create hidden cursor"); + return false; + } + + return true; + } + + void CursorImpl::Uninitialize() + { + if (s_hiddenCursor) + { + ScopedXCBConnection connection; + xcb_free_cursor(connection, s_hiddenCursor); + s_hiddenCursor = 0; + } + } + + xcb_cursor_t CursorImpl::s_hiddenCursor = 0; + + std::array CursorImpl::s_systemCursorIds = + { + { + // http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6 + "crosshair", // SystemCursor_Crosshair + "left_ptr", // SystemCursor_Default + "hand", // SystemCursor_Hand + "help", // SystemCursor_Help + "fleur", // SystemCursor_Move + nullptr, // SystemCursor_None + "hand", // SystemCursor_Pointer + "watch", // SystemCursor_Progress + "right_side", // SystemCursor_ResizeE + "top_side", // SystemCursor_ResizeN + "top_right_corner", // SystemCursor_ResizeNE + "top_left_corner", // SystemCursor_ResizeNW + "bottom_side", // SystemCursor_ResizeS + "bottom_right_corner", // SystemCursor_ResizeSE + "bottom_left_corner", // SystemCursor_ResizeSW + "left_side", // SystemCursor_ResizeW + "xterm", // SystemCursor_Text + "watch" // SystemCursor_Wait + } + }; + + static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete"); } diff --git a/src/Nazara/Utility/X11/CursorImpl.hpp b/src/Nazara/Utility/X11/CursorImpl.hpp index 41d91bcb1..4041b81ed 100644 --- a/src/Nazara/Utility/X11/CursorImpl.hpp +++ b/src/Nazara/Utility/X11/CursorImpl.hpp @@ -8,7 +8,9 @@ #define NAZARA_CURSORIMPL_HPP #include +#include #include +#include namespace Nz { @@ -16,14 +18,25 @@ namespace Nz class CursorImpl { + friend class Cursor; + public: bool Create(const Image& image, int hotSpotX, int hotSpotY); + bool Create(SystemCursor cursor); + void Destroy(); xcb_cursor_t GetCursor(); private: - xcb_cursor_t m_cursor; + static bool Initialize(); + static void Uninitialize(); + + xcb_cursor_t m_cursor = 0; + xcb_cursor_context_t* m_cursorContext = nullptr; + + static xcb_cursor_t s_hiddenCursor; + static std::array s_systemCursorIds; }; } diff --git a/src/Nazara/Utility/X11/Display.cpp b/src/Nazara/Utility/X11/Display.cpp index 63fbb65ac..1232cea64 100644 --- a/src/Nazara/Utility/X11/Display.cpp +++ b/src/Nazara/Utility/X11/Display.cpp @@ -107,11 +107,10 @@ namespace Nz sharedConnection = xcb_connect(nullptr, &screen_nbr); // Opening display failed: The best we can do at the moment is to output a meaningful error message - // and cause an abnormal program termination if (!sharedConnection || xcb_connection_has_error(sharedConnection)) { NazaraError("Failed to open xcb connection"); - std::abort(); + return false; } OpenConnection(); @@ -230,14 +229,14 @@ namespace Nz return screen_nbr; } - xcb_screen_t* X11::XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr) + xcb_screen_t* X11::XCBScreenOfDisplay(xcb_connection_t* connection, int screenIndex) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(connection)); - for (; iter.rem; --screen_nbr, xcb_screen_next (&iter)) + for (; iter.rem; --screenIndex, xcb_screen_next (&iter)) { - if (screen_nbr == 0) + if (screenIndex == 0) return iter.data; } diff --git a/src/Nazara/Utility/X11/ScopedXCB.inl b/src/Nazara/Utility/X11/ScopedXCB.inl index 8b2710a10..d9881b9af 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.inl +++ b/src/Nazara/Utility/X11/ScopedXCB.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2017 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 diff --git a/src/Nazara/Utility/X11/WindowImpl.cpp b/src/Nazara/Utility/X11/WindowImpl.cpp index 700b8c6ee..884244287 100644 --- a/src/Nazara/Utility/X11/WindowImpl.cpp +++ b/src/Nazara/Utility/X11/WindowImpl.cpp @@ -50,45 +50,7 @@ namespace Nz XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW; - xcb_cursor_t hiddenCursor = 0; - xcb_connection_t* connection = nullptr; - - void CreateHiddenCursor() - { - XCBPixmap cursorPixmap(connection); - - xcb_window_t window = X11::XCBDefaultRootWindow(connection); - - if (!cursorPixmap.Create( - 1, - window, - 1, - 1 - )) - { - NazaraError("Failed to create pixmap for hidden cursor"); - return; - } - - hiddenCursor = xcb_generate_id(connection); - - // Create the cursor, using the pixmap as both the shape and the mask of the cursor - if (!X11::CheckCookie( - connection, - xcb_create_cursor( - connection, - hiddenCursor, - cursorPixmap, - cursorPixmap, - 0, 0, 0, // Foreground RGB color - 0, 0, 0, // Background RGB color - 0, // X - 0 // Y - )) - ) - NazaraError("Failed to create hidden cursor"); - } } WindowImpl::WindowImpl(Window* parent) : @@ -96,7 +58,6 @@ namespace Nz m_style(0), m_parent(parent), m_smoothScrolling(false), - m_scrolling(0), m_mousePos(0, 0), m_keyRepeat(true) { @@ -289,7 +250,7 @@ namespace Nz if (m_window && m_ownsWindow) { // Unhide the mouse cursor (in case it was hidden) - SetCursor(Nz::WindowCursor_Default); + SetCursor(*Cursor::Get(SystemCursor_Default)); if (!X11::CheckCookie( connection, @@ -452,34 +413,13 @@ namespace Nz } } - void WindowImpl::SetCursor(Nz::WindowCursor windowCursor) - { - if (windowCursor == Nz::WindowCursor_None) - SetCursor(hiddenCursor); - else - { - const char* name = ConvertWindowCursorToXName(windowCursor); - - xcb_cursor_context_t* ctx; - if (xcb_cursor_context_new(connection, m_screen, &ctx) >= 0) - { - xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name); - SetCursor(cursor); - xcb_free_cursor(connection, cursor); - xcb_cursor_context_free(ctx); - } - } - } - void WindowImpl::SetCursor(const Cursor& cursor) { - if (!cursor.IsValid()) - { - NazaraError("Cursor is not valid"); - return; - } + xcb_cursor_t cursorImpl = cursor.m_impl->GetCursor(); + if (!X11::CheckCookie(connection, xcb_change_window_attributes(connection, m_window, XCB_CW_CURSOR, &cursorImpl))) + NazaraError("Failed to change mouse cursor"); - SetCursor(cursor.m_impl->GetCursor()); + xcb_flush(connection); } void WindowImpl::SetEventListener(bool listener) @@ -737,21 +677,11 @@ namespace Nz connection = X11::OpenConnection(); - // Create the hidden cursor - CreateHiddenCursor(); - return true; } void WindowImpl::Uninitialize() { - // Destroy the cursor - if (hiddenCursor) - { - xcb_free_cursor(connection, hiddenCursor); - hiddenCursor = 0; - } - X11::CloseConnection(connection); X11::Uninitialize(); @@ -998,53 +928,6 @@ namespace Nz } } - const char* WindowImpl::ConvertWindowCursorToXName(Nz::WindowCursor cursor) - { - // http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6 - switch (cursor) - { - case Nz::WindowCursor_Crosshair: - return "crosshair"; - case Nz::WindowCursor_Default: - return "left_ptr"; - case Nz::WindowCursor_Hand: - return "hand"; - case Nz::WindowCursor_Help: - return "help"; - case Nz::WindowCursor_Move: - return "fleur"; - case Nz::WindowCursor_None: - return "none"; // Handled in set cursor - case Nz::WindowCursor_Pointer: - return "hand"; - case Nz::WindowCursor_Progress: - return "watch"; - case Nz::WindowCursor_ResizeE: - return "right_side"; - case Nz::WindowCursor_ResizeN: - return "top_side"; - case Nz::WindowCursor_ResizeNE: - return "top_right_corner"; - case Nz::WindowCursor_ResizeNW: - return "top_left_corner"; - case Nz::WindowCursor_ResizeS: - return "bottom_side"; - case Nz::WindowCursor_ResizeSE: - return "bottom_right_corner"; - case Nz::WindowCursor_ResizeSW: - return "bottom_left_corner"; - case Nz::WindowCursor_ResizeW: - return "left_side"; - case Nz::WindowCursor_Text: - return "xterm"; - case Nz::WindowCursor_Wait: - return "watch"; - } - - NazaraError("Cursor is not handled by enumeration"); - return "X_cursor"; - } - void WindowImpl::CommonInitialize() { // Show the window @@ -1250,7 +1133,6 @@ namespace Nz // if (std::isprint(codePoint)) Is not working ? + handle combining ? { - WindowEvent event; event.type = Nz::WindowEventType_TextEntered; event.text.character = codePoint; event.text.repeated = false; @@ -1444,22 +1326,6 @@ namespace Nz } } - void WindowImpl::SetCursor(xcb_cursor_t cursor) - { - if (!X11::CheckCookie( - connection, - xcb_change_window_attributes( - connection, - m_window, - XCB_CW_CURSOR, - &cursor - )) - ) - NazaraError("Failed to change mouse cursor"); - - xcb_flush(connection); - } - void WindowImpl::SetMotifHints() { ScopedXCB error(nullptr); @@ -1528,7 +1394,7 @@ namespace Nz hints.functions |= MWM_FUNC_CLOSE; } - ScopedXCB error(xcb_request_check( + ScopedXCB propertyError(xcb_request_check( connection, xcb_change_property_checked( connection, @@ -1542,7 +1408,7 @@ namespace Nz ) )); - if (error) + if (propertyError) NazaraError("xcb_change_property failed, could not set window hints"); } else diff --git a/src/Nazara/Utility/X11/WindowImpl.hpp b/src/Nazara/Utility/X11/WindowImpl.hpp index 414140179..d82ff06cc 100644 --- a/src/Nazara/Utility/X11/WindowImpl.hpp +++ b/src/Nazara/Utility/X11/WindowImpl.hpp @@ -60,7 +60,6 @@ namespace Nz void ProcessEvents(bool block); - void SetCursor(WindowCursor cursor); void SetCursor(const Cursor& cursor); void SetEventListener(bool listener); void SetFocus(); @@ -84,7 +83,6 @@ namespace Nz void CleanUp(); xcb_keysym_t ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state); Keyboard::Key ConvertVirtualKey(xcb_keysym_t symbol); - const char* ConvertWindowCursorToXName(WindowCursor cursor); void CommonInitialize(); char32_t GetRepresentation(xcb_keysym_t keysym) const; @@ -93,7 +91,6 @@ namespace Nz void ResetVideoMode(); - void SetCursor(xcb_cursor_t cursor); void SetMotifHints(); void SetVideoMode(const VideoMode& mode); void SwitchToFullscreen(); @@ -114,7 +111,6 @@ namespace Nz bool m_ownsWindow; bool m_smoothScrolling; bool m_threadActive; - short m_scrolling; Vector2i m_mousePos; bool m_keyRepeat; diff --git a/tests/Engine/Core/ParameterList.cpp b/tests/Engine/Core/ParameterList.cpp index ef2729833..5d998f5b8 100644 --- a/tests/Engine/Core/ParameterList.cpp +++ b/tests/Engine/Core/ParameterList.cpp @@ -24,13 +24,13 @@ SCENARIO("ParameterList", "[CORE][PARAMETERLIST]") WHEN("We add Float '3.f'") { - float fl = 3.f; - parameterList.SetParameter("float", fl); + double fl = 3.f; + parameterList.SetParameter("double", fl); THEN("We can get it back") { - float newFl; - REQUIRE(parameterList.GetFloatParameter("float", &newFl)); + double newFl; + REQUIRE(parameterList.GetDoubleParameter("double", &newFl)); REQUIRE(newFl == fl); } } diff --git a/tests/Engine/Math/AlgorithmMath.cpp b/tests/Engine/Math/AlgorithmMath.cpp index 01413d902..e6dc2218b 100644 --- a/tests/Engine/Math/AlgorithmMath.cpp +++ b/tests/Engine/Math/AlgorithmMath.cpp @@ -1,5 +1,6 @@ #include #include +#include TEST_CASE("Approach", "[MATH][ALGORITHM]") { @@ -48,6 +49,11 @@ TEST_CASE("CountBits", "[MATH][ALGORITHM]") { REQUIRE(Nz::CountBits(0) == 0); } + + SECTION("Number 0xFFFFFFFF has 32 bit set to 1") + { + REQUIRE(Nz::CountBits(0xFFFFFFFF) == 32); + } } TEST_CASE("DegreeToRadian", "[MATH][ALGORITHM]") @@ -205,9 +211,19 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]") CHECK(Nz::NumberEquals(2.35, 2.35, 0.01)); } - SECTION("3 and 4 unsigned should be the same at 1") + SECTION("0 and 4 unsigned should be the same at 1") { - CHECK(Nz::NumberEquals(3U, 4U, 1U)); + CHECK(Nz::NumberEquals(0U, 4U, 4U)); + } + + SECTION("Maximum integer and -1 should not be equal") + { + CHECK_FALSE(Nz::NumberEquals(std::numeric_limits::max(), -1)); + } + + SECTION("Maximum integer and minimum integer should not be equal") + { + CHECK_FALSE(Nz::NumberEquals(std::numeric_limits::max(), std::numeric_limits::min())); } } diff --git a/tests/Engine/Math/Sphere.cpp b/tests/Engine/Math/Sphere.cpp index ef13ffb38..a6f23236d 100644 --- a/tests/Engine/Math/Sphere.cpp +++ b/tests/Engine/Math/Sphere.cpp @@ -41,12 +41,10 @@ SCENARIO("Sphere", "[MATH][SPHERE]") { THEN("These results are expected because we don't take into account the border") { - REQUIRE(firstCenterAndUnit.Distance(Nz::Vector3f::UnitX() * 2.f) == Approx(1.f)); - REQUIRE(firstCenterAndUnit.SquaredDistance(Nz::Vector3f::UnitX() * 2.f) == Approx(1.f)); + CHECK(firstCenterAndUnit.Distance(Nz::Vector3f::UnitX() * 2.f) == Approx(1.f)); Nz::Spheref tmp(Nz::Vector3f::UnitX(), 1.f); - REQUIRE(tmp.Distance(Nz::Vector3f::UnitX() * 4.f) == Approx(2.f)); - REQUIRE(tmp.SquaredDistance(Nz::Vector3f::UnitX() * 4.f) == Approx(4.f)); + CHECK(tmp.Distance(Nz::Vector3f::UnitX() * 4.f) == Approx(2.f)); } } @@ -56,7 +54,7 @@ SCENARIO("Sphere", "[MATH][SPHERE]") THEN("This is equal to sphere center and radius 0.75") { - REQUIRE(centerUnitBox.GetSquaredBoundingSphere() == Nz::Spheref(Nz::Vector3f::Zero(), 0.75f)); + CHECK(centerUnitBox.GetSquaredBoundingSphere() == Nz::Spheref(Nz::Vector3f::Zero(), 0.75f)); } } @@ -66,12 +64,12 @@ SCENARIO("Sphere", "[MATH][SPHERE]") THEN("Positive vertex should be the same with centered and unit sphere") { - REQUIRE(positiveVector == firstCenterAndUnit.GetPositiveVertex(positiveVector)); + CHECK(positiveVector == firstCenterAndUnit.GetPositiveVertex(positiveVector)); } AND_THEN("Negative vertex should be the opposite") { - REQUIRE(-positiveVector == firstCenterAndUnit.GetNegativeVertex(positiveVector)); + CHECK(-positiveVector == firstCenterAndUnit.GetNegativeVertex(positiveVector)); } } @@ -81,10 +79,12 @@ SCENARIO("Sphere", "[MATH][SPHERE]") firstCenterAndUnit.ExtendTo(point); + REQUIRE(firstCenterAndUnit.radius == Approx(2.f)); + THEN("Sphere must contain it and distance should be good") { CHECK(firstCenterAndUnit.Contains(point)); - REQUIRE(firstCenterAndUnit.Distance(point) == 1.f); + CHECK(firstCenterAndUnit.Distance(point) == Approx(0.f)); } } diff --git a/tests/Engine/Network/SocketPoller.cpp b/tests/Engine/Network/SocketPoller.cpp index 7081c1b30..2e880cf5c 100644 --- a/tests/Engine/Network/SocketPoller.cpp +++ b/tests/Engine/Network/SocketPoller.cpp @@ -27,7 +27,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]") WHEN("We register the server socket to the poller") { - REQUIRE(serverPoller.RegisterSocket(server)); + REQUIRE(serverPoller.RegisterSocket(server, Nz::SocketPollEvent_Read)); THEN("The poller should have registered our socket") { @@ -48,7 +48,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]") WHEN("We register the client socket to the poller") { - REQUIRE(serverPoller.RegisterSocket(serverToClient)); + REQUIRE(serverPoller.RegisterSocket(serverToClient, Nz::SocketPollEvent_Read)); THEN("The poller should have registered our socket") { @@ -65,7 +65,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]") REQUIRE(serverPoller.Wait(1000)); - CHECK(serverPoller.IsReady(serverToClient)); + CHECK(serverPoller.IsReadyToRead(serverToClient)); CHECK(serverToClient.Read(buffer.data(), buffer.size()) == sent); @@ -73,7 +73,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]") { REQUIRE_FALSE(serverPoller.Wait(100)); - REQUIRE_FALSE(serverPoller.IsReady(serverToClient)); + REQUIRE_FALSE(serverPoller.IsReadyToRead(serverToClient)); } } } diff --git a/tests/Engine/Utility/EventHandler/EventState.cpp b/tests/Engine/Utility/EventHandler/EventState.cpp index 4f74e3000..9fa5ea244 100644 --- a/tests/Engine/Utility/EventHandler/EventState.cpp +++ b/tests/Engine/Utility/EventHandler/EventState.cpp @@ -53,9 +53,9 @@ void EventState::AddEvent(const Nz::WindowEvent& event) m_events.push_back(Nz::String::Number(m_count) + " - " + ToString(event)); Nz::String content; - for (auto&& event : m_events) + for (auto&& currentEvent : m_events) { - content += event + "\n"; + content += currentEvent + "\n"; } content += "\nM for Menu"; m_text.SetContent(content, 36); diff --git a/tests/Engine/Utility/EventHandler/KeyState.cpp b/tests/Engine/Utility/EventHandler/KeyState.cpp index 043dc5837..6244e8ed6 100644 --- a/tests/Engine/Utility/EventHandler/KeyState.cpp +++ b/tests/Engine/Utility/EventHandler/KeyState.cpp @@ -46,7 +46,7 @@ void KeyState::DrawMenu() m_text.SetContent("Clic on a key, this text should change !\nN for alternating event\nM for Menu"); } -void KeyState::ManageInput(KeyStatus isKeyPressed, const Nz::WindowEvent::KeyEvent& key, Ndk::StateMachine& fsm) +void KeyState::ManageInput(KeyStatus /*isKeyPressed*/, const Nz::WindowEvent::KeyEvent& key, Ndk::StateMachine& fsm) { if (key.code == Nz::Keyboard::Key::M && key.shift) fsm.ChangeState(StateFactory::Get(EventStatus::Menu)); diff --git a/tests/Engine/Utility/EventHandler/MouseClickState.cpp b/tests/Engine/Utility/EventHandler/MouseClickState.cpp index 1de923bd4..bc2627195 100644 --- a/tests/Engine/Utility/EventHandler/MouseClickState.cpp +++ b/tests/Engine/Utility/EventHandler/MouseClickState.cpp @@ -58,7 +58,7 @@ void MouseClickState::DrawMenu() m_text.SetContent("Click in the windows, this text should change !\nM for Menu"); } -void MouseClickState::ManageInput(MouseStatus mouseStatus, const Nz::WindowEvent::MouseButtonEvent& mouse, Ndk::StateMachine& fsm) +void MouseClickState::ManageInput(MouseStatus mouseStatus, const Nz::WindowEvent::MouseButtonEvent& mouse, Ndk::StateMachine& /*fsm*/) { Nz::String content; if (mouseStatus == MouseStatus::Pressed) diff --git a/tests/Engine/Utility/EventHandler/Text.cpp b/tests/Engine/Utility/EventHandler/Text.cpp index 75cece5b9..98637b276 100644 --- a/tests/Engine/Utility/EventHandler/Text.cpp +++ b/tests/Engine/Utility/EventHandler/Text.cpp @@ -11,7 +11,7 @@ Text::Text(StateContext& stateContext) : m_context(stateContext) { m_text = m_context.world.CreateEntity(); - Ndk::NodeComponent& nodeComponent = m_text->AddComponent(); + m_text->AddComponent(); Ndk::GraphicsComponent& graphicsComponent = m_text->AddComponent(); m_textSprite = Nz::TextSprite::New(); diff --git a/tests/SDK/NDK/BaseSystem.cpp b/tests/SDK/NDK/BaseSystem.cpp index a202c1f70..3bb0fa9e4 100644 --- a/tests/SDK/NDK/BaseSystem.cpp +++ b/tests/SDK/NDK/BaseSystem.cpp @@ -38,7 +38,7 @@ SCENARIO("BaseSystem", "[NDK][BASESYSTEM]") WHEN("We add an entity") { - const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::EntityHandle entity = world.CreateEntity(); entity->AddComponent(); THEN("System should have it") @@ -50,7 +50,7 @@ SCENARIO("BaseSystem", "[NDK][BASESYSTEM]") WHEN("We add an entity with excluded component") { - const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::EntityHandle entity = world.CreateEntity(); entity->AddComponent(); entity->AddComponent(); diff --git a/tests/SDK/NDK/Entity.cpp b/tests/SDK/NDK/Entity.cpp index cf02370ec..dd3216fb0 100644 --- a/tests/SDK/NDK/Entity.cpp +++ b/tests/SDK/NDK/Entity.cpp @@ -57,18 +57,18 @@ SCENARIO("Entity", "[NDK][ENTITY]") { Ndk::World world; Ndk::BaseSystem& system = world.AddSystem(); - const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::EntityHandle entity = world.CreateEntity(); WHEN("We add our UpdateComponent") { UpdatableComponent& updatableComponent = entity->AddComponent(); - REQUIRE(!updatableComponent.IsUpdated()); + CHECK(!updatableComponent.IsUpdated()); THEN("Update the world should update the entity's component") { world.Update(1.f); UpdatableComponent& updatableComponentGet = entity->GetComponent(); - REQUIRE(updatableComponentGet.IsUpdated()); + CHECK(updatableComponentGet.IsUpdated()); } THEN("Update the world should not update the entity's component if it's disabled") @@ -76,14 +76,14 @@ SCENARIO("Entity", "[NDK][ENTITY]") entity->Enable(false); world.Update(1.f); UpdatableComponent& updatableComponentGet = entity->GetComponent(); - REQUIRE(!updatableComponentGet.IsUpdated()); + CHECK(!updatableComponentGet.IsUpdated()); } THEN("We can remove its component") { entity->RemoveComponent(Ndk::GetComponentIndex()); world.Update(1.f); - REQUIRE(!entity->HasComponent()); + CHECK(!entity->HasComponent()); } } @@ -94,7 +94,7 @@ SCENARIO("Entity", "[NDK][ENTITY]") THEN("It's no more valid") { - REQUIRE(!world.IsEntityValid(entity)); + CHECK(!world.IsEntityValid(entity)); } } } diff --git a/tests/SDK/NDK/EntityList.cpp b/tests/SDK/NDK/EntityList.cpp index 4b76766d5..30a57573d 100644 --- a/tests/SDK/NDK/EntityList.cpp +++ b/tests/SDK/NDK/EntityList.cpp @@ -16,8 +16,8 @@ SCENARIO("EntityList", "[NDK][ENTITYLIST]") THEN("These results are expected") { REQUIRE(entityList.Has(entity->GetId())); - const Ndk::EntityHandle& entity = world.CreateEntity(); - REQUIRE(!entityList.Has(entity->GetId())); + const Ndk::EntityHandle& newEntity = world.CreateEntity(); + REQUIRE(!entityList.Has(newEntity->GetId())); } } diff --git a/tests/SDK/NDK/EntityOwner.cpp b/tests/SDK/NDK/EntityOwner.cpp index eb9a29edf..f2fd76d58 100644 --- a/tests/SDK/NDK/EntityOwner.cpp +++ b/tests/SDK/NDK/EntityOwner.cpp @@ -7,7 +7,7 @@ SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]") GIVEN("A world & an entity") { Ndk::World world; - const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::EntityHandle entity = world.CreateEntity(); WHEN("We set the ownership of the entity to our owner") { @@ -15,13 +15,21 @@ SCENARIO("EntityOwner", "[NDK][ENTITYOWNER]") THEN("Entity is still valid") { - REQUIRE(entity.IsValid()); + CHECK(entity.IsValid()); } THEN("Resetting or getting out of scope is no more valid") { entityOwner.Reset(); world.Update(1.f); + CHECK(!entity.IsValid()); + } + + THEN("Moving an entity owner works") + { + Ndk::EntityOwner entityOwner2(std::move(entityOwner)); + entityOwner2.Reset(); + world.Update(1.f); REQUIRE(!entity.IsValid()); } } diff --git a/tests/SDK/NDK/StateMachine.cpp b/tests/SDK/NDK/StateMachine.cpp index 1c14b1e76..066a150d7 100644 --- a/tests/SDK/NDK/StateMachine.cpp +++ b/tests/SDK/NDK/StateMachine.cpp @@ -28,21 +28,79 @@ class TestState : public Ndk::State bool m_isUpdated; }; +class SecondTestState : public Ndk::State +{ + public: + void Enter(Ndk::StateMachine& /*fsm*/) override + { + m_isUpdated = false; + } + + bool IsUpdated() const + { + return m_isUpdated; + } + + void Leave(Ndk::StateMachine& /*fsm*/) override + { + } + + bool Update(Ndk::StateMachine& fsm, float /*elapsedTime*/) override + { + if (fsm.IsTopState(this)) + m_isUpdated = true; + return true; + } + + private: + bool m_isUpdated; +}; + SCENARIO("State & StateMachine", "[NDK][STATE]") { - GIVEN("A statemachine with our TestState") + GIVEN("A statemachine with our test states") { std::shared_ptr testState = std::make_shared(); - Ndk::StateMachine stateMachine(testState); + std::shared_ptr secondTestState = std::make_shared(); + Ndk::StateMachine stateMachine(secondTestState); + stateMachine.PushState(testState); REQUIRE(!testState->IsUpdated()); + REQUIRE(!secondTestState->IsUpdated()); WHEN("We update our machine") { stateMachine.Update(1.f); - THEN("Our state has been updated") + THEN("Our state on the top has been updated but not the bottom one") { + REQUIRE(stateMachine.IsTopState(testState.get())); + REQUIRE(!stateMachine.IsTopState(secondTestState.get())); + REQUIRE(testState->IsUpdated()); + REQUIRE(!secondTestState->IsUpdated()); + } + } + + WHEN("We exchange the states' positions while emptying the stack") + { + REQUIRE(stateMachine.PopStatesUntil(secondTestState)); + REQUIRE(stateMachine.IsTopState(secondTestState.get())); + + std::shared_ptr oldState = stateMachine.PopState(); + REQUIRE(stateMachine.PopState() == nullptr); + + stateMachine.SetState(testState); + stateMachine.PushState(oldState); + + stateMachine.Update(1.f); + + THEN("Both states should be updated") + { + REQUIRE(!stateMachine.IsTopState(testState.get())); + REQUIRE(stateMachine.IsTopState(secondTestState.get())); + + REQUIRE(testState->IsUpdated()); + REQUIRE(secondTestState->IsUpdated()); } } } diff --git a/tests/SDK/NDK/Systems/ListenerSystem.cpp b/tests/SDK/NDK/Systems/ListenerSystem.cpp index 2792dbc25..b83b24cd1 100644 --- a/tests/SDK/NDK/Systems/ListenerSystem.cpp +++ b/tests/SDK/NDK/Systems/ListenerSystem.cpp @@ -11,7 +11,7 @@ SCENARIO("ListenerSystem", "[NDK][LISTENERSYSTEM]") GIVEN("A world and an entity with listener & node components") { Ndk::World world; - const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::EntityHandle entity = world.CreateEntity(); Ndk::ListenerComponent& listenerComponent = entity->AddComponent(); Ndk::NodeComponent& nodeComponent = entity->AddComponent(); diff --git a/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp b/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp new file mode 100644 index 000000000..4bdb1e039 --- /dev/null +++ b/tests/SDK/NDK/Systems/PhysicsSystem2D.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include + +SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]") +{ + GIVEN("A world and an entity") + { + Ndk::World world; + const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::NodeComponent& nodeComponent = entity->AddComponent(); + Nz::Vector2f position(2.f, 3.f); + nodeComponent.SetPosition(position); + Nz::Rectf aabb(0.f, 0.f, 16.f, 18.f); + Nz::BoxCollider2DRef collisionBox = Nz::BoxCollider2D::New(aabb); + Ndk::CollisionComponent2D& collisionComponent = entity->AddComponent(collisionBox); + Ndk::PhysicsComponent2D& physicsComponent = entity->AddComponent(); + + WHEN("We update the world") + { + world.Update(1.f); + + THEN("Entity should have correct bounding box") + { + REQUIRE(nodeComponent.GetPosition() == position); + aabb.Translate(position); + REQUIRE(physicsComponent.GetAABB() == aabb); + } + } + } +} \ No newline at end of file diff --git a/tests/SDK/NDK/Systems/PhysicsSystem3D.cpp b/tests/SDK/NDK/Systems/PhysicsSystem3D.cpp index 3cb0d6bdb..b66aa89b7 100644 --- a/tests/SDK/NDK/Systems/PhysicsSystem3D.cpp +++ b/tests/SDK/NDK/Systems/PhysicsSystem3D.cpp @@ -5,7 +5,7 @@ #include #include -SCENARIO("PhysicsSystem", "[NDK][PHYSICSSYSTEM]") +SCENARIO("PhysicsSystem3D", "[NDK][PHYSICSSYSTEM3D]") { GIVEN("A world and a static entity & a dynamic entity") { diff --git a/tests/SDK/NDK/World.cpp b/tests/SDK/NDK/World.cpp index 85ee241b4..d46b6621b 100644 --- a/tests/SDK/NDK/World.cpp +++ b/tests/SDK/NDK/World.cpp @@ -79,7 +79,7 @@ SCENARIO("World", "[NDK][WORLD]") AND_WHEN("We update our world with our entity") { REQUIRE(&world.GetSystem(UpdateSystem::systemIndex) == &world.GetSystem()); - const Ndk::EntityHandle& entity = world.CreateEntity(); + Ndk::EntityHandle entity = world.CreateEntity(); UpdatableComponent& component = entity->AddComponent(); THEN("Our entity component must be updated")