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

This commit is contained in:
Lynix 2016-10-11 17:24:03 +02:00
commit cf7465f7db
94 changed files with 2443 additions and 345 deletions

23
.gitignore vendored
View File

@ -1,14 +1,26 @@
# Nazara build # Nazara build
build/config.lua build/config.lua
# Nazara libraries
lib/*
# Nazara package
package/*
# Example files
examples/bin/*.exe examples/bin/*.exe
examples/bin/*.pdb examples/bin/*.pdb
examples/bin/*.dll examples/bin/*.dll
examples/bin/*.so examples/bin/*.so
# Unit tests
tests/*.exe tests/*.exe
tests/*.pdb tests/*.pdb
tests/*.dll tests/*.dll
tests/*.so tests/*.so
lib/*
# Example generated files
examples/bin/HardwareInfo.txt
# Example generated files # Example generated files
examples/bin/HardwareInfo.txt examples/bin/HardwareInfo.txt
@ -40,7 +52,8 @@ build/**/*.sln
build/**/*.vcxprojResolveAssemblyReference.cache build/**/*.vcxprojResolveAssemblyReference.cache
build/**/*.nativecodeanalysis.all.xml build/**/*.nativecodeanalysis.all.xml
build/**/*.nativecodeanalysis.xml build/**/*.nativecodeanalysis.xml
build/**/*.VC.* build/**/*.VC.opendb
build/**/*.VC.db
# Compiled Object files # Compiled Object files
build/**/*.slo build/**/*.slo
@ -136,3 +149,9 @@ DocProject/Help/*.hhk
DocProject/Help/*.hhp DocProject/Help/*.hhp
DocProject/Help/Html2 DocProject/Help/Html2
DocProject/Help/html DocProject/Help/html

49
.travis.yml Normal file
View File

@ -0,0 +1,49 @@
language:
cpp
dist:
trusty
addons:
apt:
sources:
- llvm-toolchain-precise-3.7
- ubuntu-toolchain-r-test
packages:
- clang-3.7
- libassimp-dev
- libfreetype6-dev
- libgl1-mesa-dev
- libopenal-dev
- libsndfile1-dev
- libx11-dev
- libxcb-cursor-dev
- libxcb-ewmh-dev
- libxcb-icccm4-dev
- libxcb-keysyms1-dev
- libxcb-randr0-dev
- mesa-common-dev
sudo:
required
notifications:
email: true
compiler:
- clang
env:
- COMPILER=clang++-3.7 CONFIG=debug
- COMPILER=clang++-3.7 CONFIG=release
script:
- cd build &&
./premake5-linux64 --cc=clang gmake
- cd gmake &&
make -j4 -f NazaraEngine.make config=${CONFIG}dynamic_x64
after_script:
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib/gmake/x64/:../extlibs/lib/gmake/x64/ &&
cd ../../tests &&
./NazaraUnitTestsServer

View File

@ -34,21 +34,21 @@ namespace Ndk
inline void EnsureViewMatrixUpdate() const; inline void EnsureViewMatrixUpdate() const;
inline void EnsureViewportUpdate() const; inline void EnsureViewportUpdate() const;
inline float GetAspectRatio() const override; float GetAspectRatio() const override;
inline Nz::Vector3f GetEyePosition() const override; Nz::Vector3f GetEyePosition() const override;
inline Nz::Vector3f GetForward() const override; Nz::Vector3f GetForward() const override;
inline float GetFOV() const; inline float GetFOV() const;
inline const Nz::Frustumf& GetFrustum() const override; const Nz::Frustumf& GetFrustum() const override;
inline unsigned int GetLayer() const; inline unsigned int GetLayer() const;
inline const Nz::Matrix4f& GetProjectionMatrix() const override; const Nz::Matrix4f& GetProjectionMatrix() const override;
inline Nz::ProjectionType GetProjectionType() const; inline Nz::ProjectionType GetProjectionType() const;
inline const Nz::Vector2f& GetSize() const; inline const Nz::Vector2f& GetSize() const;
inline const Nz::RenderTarget* GetTarget() const override; const Nz::RenderTarget* GetTarget() const override;
inline const Nz::Rectf& GetTargetRegion() const; inline const Nz::Rectf& GetTargetRegion() const;
inline const Nz::Matrix4f& GetViewMatrix() const override; const Nz::Matrix4f& GetViewMatrix() const override;
inline const Nz::Recti& GetViewport() const override; const Nz::Recti& GetViewport() const override;
inline float GetZFar() const override; float GetZFar() const override;
inline float GetZNear() const override; float GetZNear() const override;
inline void SetFOV(float fov); inline void SetFOV(float fov);
inline void SetLayer(unsigned int layer); inline void SetLayer(unsigned int layer);

View File

@ -95,40 +95,15 @@ namespace Ndk
UpdateViewport(); UpdateViewport();
} }
/*!
* \brief Gets the aspect ratio of the camera
* \return Aspect ratio of the camera
*/
inline float CameraComponent::GetAspectRatio() const
{
EnsureViewportUpdate();
return m_aspectRatio;
}
/*! /*!
* \brief Gets the field of view of the camera * \brief Gets the field of view of the camera
* \return Field of view of the camera * \return Field of view of the camera
*/ */
float CameraComponent::GetFOV() const
inline float CameraComponent::GetFOV() const
{ {
return m_fov; return m_fov;
} }
/*!
* \brief Gets the frutum of the camera
* \return A constant reference to the frustum of the camera
*/
inline const Nz::Frustumf& CameraComponent::GetFrustum() const
{
EnsureFrustumUpdate();
return m_frustum;
}
/*! /*!
* \brief Gets the layer of the camera * \brief Gets the layer of the camera
* \return Layer of the camera * \return Layer of the camera
@ -139,18 +114,6 @@ namespace Ndk
return m_layer; return m_layer;
} }
/*!
* \brief Gets the projection matrix of the camera
* \return A constant reference to the projection matrix of the camera
*/
inline const Nz::Matrix4f& CameraComponent::GetProjectionMatrix() const
{
EnsureProjectionMatrixUpdate();
return m_projectionMatrix;
}
/*! /*!
* \brief Gets the projection type of the camera * \brief Gets the projection type of the camera
* \return Projection type of the camera * \return Projection type of the camera
@ -171,16 +134,6 @@ namespace Ndk
return m_size; return m_size;
} }
/*!
* \brief Gets the target of the camera
* \return A constant reference to the render target of the camera
*/
inline const Nz::RenderTarget* CameraComponent::GetTarget() const
{
return m_target;
}
/*! /*!
* \brief Gets the target region of the camera * \brief Gets the target region of the camera
* \return A constant reference to the target region of the camera * \return A constant reference to the target region of the camera
@ -191,50 +144,6 @@ namespace Ndk
return m_targetRegion; return m_targetRegion;
} }
/*!
* \brief Gets the view matrix of the camera
* \return A constant reference to the view matrix of the camera
*/
inline const Nz::Matrix4f& CameraComponent::GetViewMatrix() const
{
EnsureViewMatrixUpdate();
return m_viewMatrix;
}
/*!
* \brief Gets the view port of the camera
* \return A constant reference to the view port of the camera
*/
inline const Nz::Recti& CameraComponent::GetViewport() const
{
EnsureViewportUpdate();
return m_viewport;
}
/*!
* \brief Gets the Z far distance of the camera
* \return Z far distance of the camera
*/
inline float CameraComponent::GetZFar() const
{
return m_zFar;
}
/*!
* \brief Gets the Z near distance of the camera
* \return Z near distance of the camera
*/
inline float CameraComponent::GetZNear() const
{
return m_zNear;
}
/*! /*!
* \brief Sets the field of view of the camera * \brief Sets the field of view of the camera
* *

View File

@ -51,7 +51,7 @@ namespace Ndk
inline bool IsVisible() const; inline bool IsVisible() const;
void SendCharacter(char32_t character); void SendCharacter(char32_t character);
void SendEvent(Nz::WindowEvent event); void SendEvent(const Nz::WindowEvent& event);
void SetCharacterSize(unsigned int size); void SetCharacterSize(unsigned int size);
void SetSize(const Nz::Vector2f& size); void SetSize(const Nz::Vector2f& size);

View File

@ -27,32 +27,15 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
// Version of SDK
#define NDK_VERSION_MAJOR 0
#define NDK_VERSION_MINOR 1
// Importation/Exportation of the API // Importation/Exportation of the API
#if defined(NAZARA_PLATFORM_WINDOWS) #if defined(NAZARA_STATIC)
#if !defined(NDK_STATIC) #define #define NDK_API
#ifdef NDK_BUILD
#define NDK_API NAZARA_EXPORT
#else
#define NDK_API NAZARA_IMPORT
#endif
#else
#define NDK_API
#endif
#elif defined(NAZARA_PLATFORM_LINUX)
#if !defined(NDK_STATIC) && defined(NAZARA_COMPILER_GCC)
#define NDK_API NAZARA_EXPORT
#else
#define NDK_API
#endif
#else #else
// To comment to force a compilation #ifdef NDK_BUILD
#error This operating system is not fully supported by the Nazara Development Kit #define NDK_API NAZARA_EXPORT
#else
#define NDK_API #define NDK_API NAZARA_IMPORT
#endif
#endif #endif
namespace Ndk namespace Ndk

View File

@ -34,7 +34,7 @@ namespace Ndk
* *
* \remark Only one Application instance can exist at a time * \remark Only one Application instance can exist at a time
*/ */
inline Application::Application(int argc, char* argv[]) : Application::Application(int argc, char* argv[]) :
Application() Application()
{ {
std::regex optionRegex(R"(-(\w+))"); std::regex optionRegex(R"(-(\w+))");

View File

@ -35,6 +35,17 @@ namespace Ndk
Nz::Renderer::SetViewport(m_viewport); Nz::Renderer::SetViewport(m_viewport);
} }
/*!
* \brief Gets the aspect ratio of the camera
* \return Aspect ratio of the camera
*/
float CameraComponent::GetAspectRatio() const
{
EnsureViewportUpdate();
return m_aspectRatio;
}
/*! /*!
* \brief Gets the eye position of the camera * \brief Gets the eye position of the camera
* *
@ -53,7 +64,6 @@ namespace Ndk
* *
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent * \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
*/ */
Nz::Vector3f CameraComponent::GetForward() const Nz::Vector3f CameraComponent::GetForward() const
{ {
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent"); NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
@ -61,6 +71,76 @@ namespace Ndk
return m_entity->GetComponent<NodeComponent>().GetForward(); return m_entity->GetComponent<NodeComponent>().GetForward();
} }
/*!
* \brief Gets the frutum of the camera
* \return A constant reference to the frustum of the camera
*/
const Nz::Frustumf& CameraComponent::GetFrustum() const
{
EnsureFrustumUpdate();
return m_frustum;
}
/*!
* \brief Gets the projection matrix of the camera
* \return A constant reference to the projection matrix of the camera
*/
const Nz::Matrix4f& CameraComponent::GetProjectionMatrix() const
{
EnsureProjectionMatrixUpdate();
return m_projectionMatrix;
}
/*!
* \brief Gets the target of the camera
* \return A constant reference to the render target of the camera
*/
const Nz::RenderTarget* CameraComponent::GetTarget() const
{
return m_target;
}
/*!
* \brief Gets the view matrix of the camera
* \return A constant reference to the view matrix of the camera
*/
const Nz::Matrix4f& CameraComponent::GetViewMatrix() const
{
EnsureViewMatrixUpdate();
return m_viewMatrix;
}
/*!
* \brief Gets the view port of the camera
* \return A constant reference to the view port of the camera
*/
const Nz::Recti& CameraComponent::GetViewport() const
{
EnsureViewportUpdate();
return m_viewport;
}
/*!
* \brief Gets the Z far distance of the camera
* \return Z far distance of the camera
*/
float CameraComponent::GetZFar() const
{
return m_zFar;
}
/*!
* \brief Gets the Z near distance of the camera
* \return Z near distance of the camera
*/
float CameraComponent::GetZNear() const
{
return m_zNear;
}
/*! /*!
* \brief Sets the layer of the camera in case of multiples fields * \brief Sets the layer of the camera in case of multiples fields
* *

View File

@ -168,7 +168,7 @@ namespace Ndk
* \param event Event to be takin into consideration by the console * \param event Event to be takin into consideration by the console
*/ */
void Console::SendEvent(Nz::WindowEvent event) void Console::SendEvent(const Nz::WindowEvent& event)
{ {
switch (event.type) switch (event.type)
{ {
@ -204,6 +204,9 @@ namespace Ndk
} }
break; break;
} }
default:
break;
} }
} }

View File

@ -78,9 +78,10 @@ namespace Ndk
}); });
/*********************************** Nz::SoundBuffer **********************************/ /*********************************** Nz::SoundBuffer **********************************/
soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance) soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance, std::size_t argumentCount)
{ {
NazaraUnused(lua); NazaraUnused(lua);
NazaraUnused(argumentCount);
Nz::PlacementNew(instance, Nz::SoundBuffer::New()); Nz::PlacementNew(instance, Nz::SoundBuffer::New());
return true; return true;

View File

@ -13,7 +13,7 @@ namespace Ndk
void LuaBinding::BindCore() void LuaBinding::BindCore()
{ {
/*********************************** Nz::Clock **********************************/ /*********************************** Nz::Clock **********************************/
clockClass.SetConstructor([](Nz::LuaInstance& lua, Nz::Clock* clock) clockClass.SetConstructor([](Nz::LuaInstance& lua, Nz::Clock* clock, std::size_t argumentCount)
{ {
int argIndex = 1; int argIndex = 1;
Nz::Int64 startingValue = lua.Check<Nz::Int64>(&argIndex, 0); Nz::Int64 startingValue = lua.Check<Nz::Int64>(&argIndex, 0);
@ -44,9 +44,9 @@ namespace Ndk
}); });
/********************************* Nz::Directory ********************************/ /********************************* Nz::Directory ********************************/
directoryClass.SetConstructor([](Nz::LuaInstance& lua, Nz::Directory* directory) directoryClass.SetConstructor([](Nz::LuaInstance& lua, Nz::Directory* directory, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 1U); std::size_t argCount = std::min<std::size_t>(argumentCount, 1U);
int argIndex = 1; int argIndex = 1;
switch (argCount) switch (argCount)
@ -138,9 +138,9 @@ namespace Ndk
/*********************************** Nz::File ***********************************/ /*********************************** Nz::File ***********************************/
fileClass.Inherit(streamClass); fileClass.Inherit(streamClass);
fileClass.SetConstructor([](Nz::LuaInstance& lua, Nz::File* file) fileClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::File* file, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 2U); std::size_t argCount = std::min<std::size_t>(argumentCount, 1U);
int argIndex = 1; int argIndex = 1;
switch (argCount) switch (argCount)

View File

@ -20,8 +20,10 @@ namespace Ndk
return reinterpret_cast<Nz::InstancedRenderableRef*>(model); //TODO: Make a ObjectRefCast return reinterpret_cast<Nz::InstancedRenderableRef*>(model); //TODO: Make a ObjectRefCast
}); });
modelClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::ModelRef* model) modelClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::ModelRef* model, std::size_t argumentCount)
{ {
NazaraUnused(argumentCount);
Nz::PlacementNew(model, Nz::Model::New()); Nz::PlacementNew(model, Nz::Model::New());
return true; return true;
}); });

View File

@ -14,9 +14,10 @@ namespace Ndk
void LuaBinding::BindMath() void LuaBinding::BindMath()
{ {
/*********************************** Nz::EulerAngles **********************************/ /*********************************** Nz::EulerAngles **********************************/
eulerAnglesClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::EulerAnglesd* angles) eulerAnglesClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::EulerAnglesd* angles, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 3U); std::size_t argCount = std::min<std::size_t>(argumentCount, 1U);
switch (argCount) switch (argCount)
{ {
case 0: case 0:
@ -154,9 +155,10 @@ namespace Ndk
}); });
/*********************************** Nz::Rect **********************************/ /*********************************** Nz::Rect **********************************/
rectClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Rectd* rect) rectClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Rectd* rect, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 4U); std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
switch (argCount) switch (argCount)
{ {
case 0: case 0:
@ -309,9 +311,10 @@ namespace Ndk
}); });
/*********************************** Nz::Quaternion **********************************/ /*********************************** Nz::Quaternion **********************************/
quaternionClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Quaterniond* quaternion) quaternionClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Quaterniond* quaternion, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 4U); std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
switch (argCount) switch (argCount)
{ {
case 0: case 0:
@ -337,6 +340,9 @@ namespace Ndk
case 4: case 4:
Nz::PlacementNew(quaternion, lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3), lua.CheckNumber(4)); Nz::PlacementNew(quaternion, lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3), lua.CheckNumber(4));
return true; return true;
default:
break;
} }
lua.Error("No matching overload for Quaternion constructor"); lua.Error("No matching overload for Quaternion constructor");
@ -411,9 +417,10 @@ namespace Ndk
}); });
/*********************************** Nz::Vector2 **********************************/ /*********************************** Nz::Vector2 **********************************/
vector2dClass.SetConstructor([](Nz::LuaInstance& lua, Nz::Vector2d* vector) vector2dClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector2d* vector, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 2U); std::size_t argCount = std::min<std::size_t>(argumentCount, 2U);
switch (argCount) switch (argCount)
{ {
case 0: case 0:
@ -533,9 +540,10 @@ namespace Ndk
}); });
/*********************************** Nz::Vector3 **********************************/ /*********************************** Nz::Vector3 **********************************/
vector3dClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector3d* vector) vector3dClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector3d* vector, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 3U); std::size_t argCount = std::min<std::size_t>(argumentCount, 3U);
switch (argCount) switch (argCount)
{ {
case 0: case 0:
@ -546,7 +554,7 @@ namespace Ndk
case 1: case 1:
{ {
if (lua.IsOfType(1, Nz::LuaType_Number)) if (lua.IsOfType(1, Nz::LuaType_Number))
Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast<Nz::Vector2d*>(lua.CheckUserdata(1, "Vector2"))); Nz::PlacementNew(vector, lua.CheckNumber(1));
else if (lua.IsOfType(1, "Vector2")) else if (lua.IsOfType(1, "Vector2"))
Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1))); Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1)));
else if (lua.IsOfType(1, "Vector3")) else if (lua.IsOfType(1, "Vector3"))
@ -560,7 +568,7 @@ namespace Ndk
case 2: case 2:
{ {
if (lua.IsOfType(1, Nz::LuaType_Number)) if (lua.IsOfType(1, Nz::LuaType_Number))
Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast<Nz::Vector2d*>(lua.CheckUserdata(1, "Vector2"))); Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast<Nz::Vector2d*>(lua.CheckUserdata(2, "Vector2")));
else if (lua.IsOfType(1, "Vector2")) else if (lua.IsOfType(1, "Vector2"))
Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1)), lua.CheckNumber(2)); Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1)), lua.CheckNumber(2));
else else

View File

@ -21,9 +21,9 @@ namespace Ndk
abstractSocketClass.BindMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes); abstractSocketClass.BindMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes);
/*********************************** Nz::IpAddress **********************************/ /*********************************** Nz::IpAddress **********************************/
ipAddressClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::IpAddress* address) ipAddressClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::IpAddress* address, std::size_t argumentCount)
{ {
unsigned int argCount = std::min(lua.GetStackTop(), 9U); std::size_t argCount = std::min<std::size_t>(argumentCount, 9U);
int argIndex = 1; int argIndex = 1;
switch (argCount) switch (argCount)

View File

@ -233,6 +233,9 @@ namespace Ndk
return &m_componentBinding[it->second]; return &m_componentBinding[it->second];
} }
default:
break;
} }
instance.Error("Invalid component index at #" + Nz::String::Number(argIndex)); instance.Error("Invalid component index at #" + Nz::String::Number(argIndex));

View File

@ -93,8 +93,10 @@ namespace Ndk
}); });
/*********************************** Nz::Font **********************************/ /*********************************** Nz::Font **********************************/
fontClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::FontRef* font) fontClass.SetConstructor([] (Nz::LuaInstance& lua, Nz::FontRef* font, std::size_t argumentCount)
{ {
NazaraUnused(argumentCount);
Nz::PlacementNew(font, Nz::Font::New()); Nz::PlacementNew(font, Nz::Font::New());
return true; return true;
}); });

View File

@ -59,6 +59,13 @@ namespace Ndk
// Initialize the engine first // Initialize the engine first
// Shared modules // Shared modules
#ifdef NDK_SERVER
Nz::ParameterList parameters;
parameters.SetParameter("NoWindowSystem", true);
Nz::Utility::SetParameters(parameters);
#endif
Nz::Lua::Initialize(); Nz::Lua::Initialize();
Nz::Noise::Initialize(); Nz::Noise::Initialize();
Nz::Physics::Initialize(); Nz::Physics::Initialize();

View File

@ -2,6 +2,20 @@ version: '{branch}-rev{build}'
shallow_clone: true shallow_clone: true
skip_commits:
files:
- .travis.yml
- Doxyfile
- LICENSE
- License-Cabin.txt
- Logo.png
- LogoMini.png
- readme.md
- readme_fr.md
- 'writing style.md'
- doc/*
- NazaraModuleTemplate/*
os: os:
- Visual Studio 2015 - Visual Studio 2015
@ -16,5 +30,20 @@ configuration:
- DebugDynamic - DebugDynamic
- ReleaseDynamic - ReleaseDynamic
platform:
- Win32
- x64
build: build:
project: build/$(TOOLSET)/NazaraEngine.sln project: build/$(TOOLSET)/NazaraEngine.sln
after_build:
- cd build && "./premake5.exe" package && cd ../package
- 7z a NazaraEngine.7z * && cd ..
artifacts:
- path: package/NazaraEngine.7z
name: 'NazaraEngine-$(CONFIGURATION)-$(PLATFORM)-$(APPVEYOR_REPO_COMMIT)'
on_success:
- cd tests && "./NazaraUnitTestsServer.exe"

View File

@ -0,0 +1,2 @@
premake5 package
pause

2
build/Package_MSVC.bat Normal file
View File

@ -0,0 +1,2 @@
premake5 --pack-libdir=msvc package
pause

2
build/Package_MinGW.bat Normal file
View File

@ -0,0 +1,2 @@
premake5 --pack-libdir=mingw package
pause

View File

@ -0,0 +1,207 @@
newoption({
trigger = "pack-libdir",
description = "Specifiy the subdirectory in lib/ to be used when packaging the project"
})
ACTION.Name = "Package"
ACTION.Description = "Pack Nazara binaries/include/lib together"
ACTION.Function = function ()
local libDir = _OPTIONS["pack-libdir"]
if (not libDir or #libDir == 0) then
local libDirs = os.matchdirs("../lib/*")
if (#libDirs > 1) then
error("More than one subdirectory was found in the lib directory, please use the --pack-libdir command to clarify which directory should be used")
elseif (#libDirs == 0) then
error("No subdirectory was found in the lib directory, have you built the engine yet?")
else
libDir = path.getname(libDirs[1])
print("No directory was set by the --pack-libdir command, \"" .. libDir .. "\" will be used")
end
end
local realLibDir = "../lib/" .. libDir .. "/"
if (not os.isdir(realLibDir)) then
error(string.format("\"%s\" doesn't seem to be an existing directory", realLibDir))
end
local archEnabled = {
["x64"] = false,
["x86"] = false
}
local enabledArchs = {}
for k,v in pairs(os.matchdirs(realLibDir .. "*")) do
local arch = path.getname(v)
if (archEnabled[arch] ~= nil) then
archEnabled[arch] = true
table.insert(enabledArchs, arch)
else
print("Unknown directory " .. v .. " found, ignored")
end
end
enabledArchs = table.concat(enabledArchs, ", ")
print(enabledArchs .. " arch found")
local packageDir = "../package/"
local copyTargets = {
{ -- Engine headers
Masks = {"**.hpp", "**.inl"},
Source = "../include/",
Target = "include/"
},
{ -- SDK headers
Masks = {"**.hpp", "**.inl"},
Source = "../SDK/include/",
Target = "include/"
},
{ -- Examples files
Masks = {"**.hpp", "**.inl", "**.cpp"},
Source = "../examples/",
Target = "examples/"
},
{ -- Demo resources
Masks = {"**.*"},
Source = "../examples/bin/resources/",
Target = "examples/bin/resources/"
},
-- Unit test sources
{
Masks = {"**.hpp", "**.inl", "**.cpp"},
Source = "../tests/",
Target = "tests/src/"
},
-- Unit test resources
{
Masks = {"**.*"},
Source = "../tests/resources/",
Target = "tests/resources/"
}
}
local binFileMasks
local libFileMasks
local exeFileExt
local exeFilterFunc
if (os.is("windows")) then
binFileMasks = {"**.dll"}
libFileMasks = {"**.lib", "**.a"}
exeFileExt = ".exe"
exeFilterFunc = function (filePath) return true end
else
if (os.is("macosx")) then
binFileMasks = {"**.dynlib"}
else
binFileMasks = {"**.so"}
end
libFileMasks = {"**.a"}
exeFileExt = ""
exeFilterFunc = function (filePath) return path.getextension(filePath):contains('/') end
end
for arch, enabled in pairs(archEnabled) do
if (enabled) then
local archLibSrc = realLibDir .. arch .. "/"
local arch3rdPartyBinSrc = "../extlibs/lib/common/" .. arch .. "/"
local archBinDst = "bin/" .. arch .. "/"
local archLibDst = "lib/" .. arch .. "/"
-- Engine/SDK binaries
table.insert(copyTargets, {
Masks = binFileMasks,
Source = archLibSrc,
Target = archBinDst
})
-- Engine/SDK libraries
table.insert(copyTargets, {
Masks = libFileMasks,
Source = archLibSrc,
Target = archLibDst
})
-- 3rd party binary dep
table.insert(copyTargets, {
Masks = binFileMasks,
Source = arch3rdPartyBinSrc,
Target = archBinDst
})
end
end
-- Demo executable
table.insert(copyTargets, {
Masks = {"Demo*" .. exeFileExt},
Filter = exeFilterFunc,
Source = "../examples/bin/",
Target = "examples/bin/"
})
-- Unit test
table.insert(copyTargets, {
Masks = {"*" .. exeFileExt},
Filter = exeFilterFunc,
Source = "../tests/",
Target = "tests/"
})
-- Processing
os.mkdir(packageDir)
local size = 0
for k,v in pairs(copyTargets) do
local target = packageDir .. v.Target
local includePrefix = v.Source
local targetFiles = {}
for k, mask in pairs(v.Masks) do
print(includePrefix .. mask .. " => " .. target)
local files = os.matchfiles(includePrefix .. mask)
if (v.Filter) then
for k,path in pairs(files) do
if (not v.Filter(path)) then
files[k] = nil
end
end
end
targetFiles = table.join(targetFiles, files)
end
for k,v in pairs(targetFiles) do
local relPath = v:sub(#includePrefix + 1)
local targetPath = target .. relPath
local targetDir = path.getdirectory(targetPath)
if (not os.isdir(targetDir)) then
local ok, err = os.mkdir(targetDir)
if (not ok) then
print("Failed to create directory \"" .. targetDir .. "\": " .. err)
end
end
local ok, err
if (os.is("windows")) then
ok, err = os.copyfile(v, targetPath)
else
-- Workaround: As premake is translating this to "cp %s %s", it fails if space are presents in source/destination paths.
ok, err = os.copyfile(string.format("\"%s\"", v), string.format("\"%s\"", targetPath))
end
if (not ok) then
print("Failed to copy \"" .. v .. "\" to \"" .. targetPath .. "\": " .. err)
end
local stat = os.stat(targetPath)
if (stat) then
size = size + stat.size
end
end
end
local config = libDir .. " - " .. enabledArchs
print(string.format("Package successfully created at \"%s\" (%u MB, %s)", packageDir, size / (1024 * 1024), config))
end

View File

@ -141,7 +141,6 @@ function NazaraBuild:Execute()
configuration("Release*") configuration("Release*")
flags("NoFramePointer") flags("NoFramePointer")
optimize("Speed") optimize("Speed")
rtti("Off")
vectorextensions("SSE2") vectorextensions("SSE2")
configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"})
@ -228,6 +227,7 @@ function NazaraBuild:Execute()
targetdir("../lib/xcode/x64") targetdir("../lib/xcode/x64")
configuration("*Static") configuration("*Static")
defines("NAZARA_STATIC")
kind("StaticLib") kind("StaticLib")
configuration("*Dynamic") configuration("*Dynamic")
@ -242,6 +242,9 @@ function NazaraBuild:Execute()
configuration("DebugDynamic") configuration("DebugDynamic")
targetsuffix("-d") targetsuffix("-d")
configuration("Release*")
rtti(moduleTable.EnableRTTI and "On" or "Off")
configuration({}) configuration({})
files(moduleTable.Files) files(moduleTable.Files)
@ -357,6 +360,12 @@ function NazaraBuild:Execute()
targetdir("../plugins/" .. toolTable.Name .. "/lib/xcode/x64") targetdir("../plugins/" .. toolTable.Name .. "/lib/xcode/x64")
end end
configuration("*Static")
defines("NAZARA_STATIC")
configuration("Release*")
rtti(toolTable.EnableRTTI and "On" or "Off")
if (toolTable.Kind == "library" or toolTable.Kind == "plugin") then if (toolTable.Kind == "library" or toolTable.Kind == "plugin") then
configuration("*Static") configuration("*Static")
kind("StaticLib") kind("StaticLib")
@ -430,6 +439,9 @@ function NazaraBuild:Execute()
includedirs(exampleTable.Includes) includedirs(exampleTable.Includes)
links(exampleTable.Libraries) links(exampleTable.Libraries)
configuration("Release*")
rtti(exampleTable.EnableRTTI and "On" or "Off")
configuration("x32") configuration("x32")
libdirs(exampleTable.LibraryPaths.x86) libdirs(exampleTable.LibraryPaths.x86)
@ -705,7 +717,7 @@ function NazaraBuild:MakeInstallCommands(infoTable)
end end
if (os.is("windows")) then if (os.is("windows")) then
configuration({}) configuration("*Dynamic")
for k,v in pairs(self.InstallDir) do for k,v in pairs(self.InstallDir) do
local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k)

View File

@ -14,6 +14,16 @@ MODULE.OsFiles.Posix = {
"../src/Nazara/Network/Posix/**.cpp" "../src/Nazara/Network/Posix/**.cpp"
} }
MODULE.OsFiles.Linux = {
"../src/Nazara/Network/Linux/**.hpp",
"../src/Nazara/Network/Linux/**.cpp"
}
MODULE.OsFilesExcluded.Linux = {
"../src/Nazara/Network/Posix/SocketPollerImpl.hpp",
"../src/Nazara/Network/Posix/SocketPollerImpl.cpp"
}
MODULE.OsLibraries.Windows = { MODULE.OsLibraries.Windows = {
"ws2_32" "ws2_32"
} }

View File

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

View File

@ -19,5 +19,6 @@ TOOL.Files = {
} }
TOOL.Libraries = { TOOL.Libraries = {
"NazaraNetwork",
"NazaraSDK" "NazaraSDK"
} }

View File

@ -0,0 +1,34 @@
TOOL.Name = "UnitTestsServer"
TOOL.Directory = "../tests"
TOOL.EnableConsole = true
TOOL.Kind = "Application"
TOOL.TargetDirectory = TOOL.Directory
TOOL.Defines = {
"NDK_SERVER"
}
TOOL.Includes = {
"../include"
}
TOOL.Files = {
"../tests/main.cpp",
"../tests/Engine/**.cpp",
"../tests/SDK/**.cpp"
}
-- Excludes client-only files
TOOL.FilesExcluded = {
"../tests/Engine/Audio/**",
"../tests/Engine/Graphics/**",
"../tests/SDK/NDK/Application.cpp",
"../tests/SDK/NDK/Systems/ListenerSystem.cpp",
"../tests/SDK/NDK/Systems/RenderSystem.cpp"
}
TOOL.Libraries = {
"NazaraNetwork",
"NazaraSDKServer"
}

View File

@ -1 +0,0 @@
ca02549e21a494540751b65126dcee5fddfb84db

View File

@ -11,6 +11,7 @@
#include <Nazara/Core/Enums.hpp> #include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/SerializationContext.hpp> #include <Nazara/Core/SerializationContext.hpp>
#include <functional> #include <functional>
#include <string>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
@ -38,11 +39,13 @@ namespace Nz
struct TypeTag {}; struct TypeTag {};
inline bool Serialize(SerializationContext& context, bool value); inline bool Serialize(SerializationContext& context, bool value);
inline bool Serialize(SerializationContext& context, const std::string& value);
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value); std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value);
inline bool Unserialize(SerializationContext& context, bool* value); inline bool Unserialize(SerializationContext& context, bool* value);
inline bool Unserialize(SerializationContext& context, std::string* value);
template<typename T> template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value); std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value);

View File

@ -6,6 +6,7 @@
// Merci à Ryan "FullMetal Alchemist" Lahfa // Merci à Ryan "FullMetal Alchemist" Lahfa
// Merci aussi à Freedom de siteduzero.com // Merci aussi à Freedom de siteduzero.com
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/AbstractHash.hpp> #include <Nazara/Core/AbstractHash.hpp>
#include <Nazara/Core/ByteArray.hpp> #include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
@ -192,7 +193,7 @@ namespace Nz
/*! /*!
* \ingroup core * \ingroup core
* \brief Serializes a boolean * \brief Serializes a boolean
* \return true if serialization succedeed * \return true if serialization succeeded
* *
* \param context Context for the serialization * \param context Context for the serialization
* \param value Boolean to serialize * \param value Boolean to serialize
@ -216,10 +217,26 @@ namespace Nz
return true; return true;
} }
/*!
* \ingroup core
* \brief Serializes a std::string
* \return true if successful
*
* \param context Context for the serialization
* \param value String to serialize
*/
bool Serialize(SerializationContext& context, const std::string& value)
{
if (!Serialize(context, UInt32(value.size())))
return false;
return context.stream->Write(value.data(), value.size()) == value.size();
}
/*! /*!
* \ingroup core * \ingroup core
* \brief Serializes an arithmetic type * \brief Serializes an arithmetic type
* \return true if serialization succedeed * \return true if serialization succeeded
* *
* \param context Context for the serialization * \param context Context for the serialization
* \param value Arithmetic type to serialize * \param value Arithmetic type to serialize
@ -266,6 +283,23 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Unserializes a string
* \return true if successful
*
* \param context Context of unserialization
* \param string std::string to unserialize
*/
bool Unserialize(SerializationContext& context, std::string* string)
{
UInt32 size;
if (!Unserialize(context, &size))
return false;
string->resize(size);
return context.stream->Read(&string[0], size) == size;
}
/*! /*!
* \ingroup core * \ingroup core
* \brief Unserializes an arithmetic type * \brief Unserializes an arithmetic type

View File

@ -64,6 +64,9 @@ namespace Nz
void Set(std::size_t bit, bool val = true); void Set(std::size_t bit, bool val = true);
void SetBlock(std::size_t i, Block block); void SetBlock(std::size_t i, Block block);
void ShiftLeft(std::size_t pos);
void ShiftRight(std::size_t pos);
void Swap(Bitset& bitset); void Swap(Bitset& bitset);
bool Test(std::size_t bit) const; bool Test(std::size_t bit) const;
@ -88,6 +91,12 @@ namespace Nz
template<typename T> Bitset& operator=(T value); template<typename T> Bitset& operator=(T value);
Bitset& operator=(Bitset&& bitset) noexcept = default; Bitset& operator=(Bitset&& bitset) noexcept = default;
Bitset operator<<(std::size_t pos) const;
Bitset& operator<<=(std::size_t pos);
Bitset operator>>(std::size_t pos) const;
Bitset& operator>>=(std::size_t pos);
Bitset& operator&=(const Bitset& bitset); Bitset& operator&=(const Bitset& bitset);
Bitset& operator|=(const Bitset& bitset); Bitset& operator|=(const Bitset& bitset);
Bitset& operator^=(const Bitset& bitset); Bitset& operator^=(const Bitset& bitset);

View File

@ -2,8 +2,10 @@
// This file is part of the "Nazara Engine - Core module" // This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Algorithm.hpp> #include <Nazara/Math/Algorithm.hpp>
#include <cstdlib>
#include <limits> #include <limits>
#include <utility> #include <utility>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
@ -512,12 +514,117 @@ namespace Nz
ResetExtraBits(); ResetExtraBits();
} }
/*!
* \brief Shift all the bits toward the left
*
* \param pos Bit shifting to be applied
*
* \remark This does not changes the size of the bitset.
*
* \see operator<<=
*/
template<typename Block, class Allocator>
void Bitset<Block, Allocator>::ShiftLeft(std::size_t pos)
{
if (pos == 0)
return;
if (pos >= m_bitCount)
{
Reset();
return;
}
auto div = std::lldiv(pos, bitsPerBlock);
if (div.rem != 0)
{
std::size_t lastIndex = m_blocks.size() - 1;
std::size_t remaining = bitsPerBlock - div.rem;
for (std::size_t i = lastIndex - div.quot; i > 0; --i)
m_blocks[i + div.quot] = (m_blocks[i] << div.rem) | (m_blocks[i - 1] >> remaining);
m_blocks[div.quot] = m_blocks[0] << div.rem;
std::fill_n(m_blocks.begin(), div.quot, Block(0));
}
else
{
for (auto it = m_blocks.rbegin(); it != m_blocks.rend(); ++it)
{
if (static_cast<std::size_t>(std::distance(m_blocks.rbegin(), it) + div.quot) < m_blocks.size())
{
auto shiftedIt = it;
std::advance(shiftedIt, div.quot);
*it = *shiftedIt;
}
else
*it = 0U;
}
}
ResetExtraBits();
}
/*!
* \brief Shift all the bits toward the right
*
* \param pos Bit shifting to be applied
*
* \remark This does not changes the size of the bitset.
*
* \see operator>>=
*/
template<typename Block, class Allocator>
void Bitset<Block, Allocator>::ShiftRight(std::size_t pos)
{
if (pos == 0)
return;
if (pos >= m_bitCount)
{
Reset();
return;
}
auto div = std::lldiv(pos, bitsPerBlock);
if (div.rem != 0)
{
std::size_t lastIndex = m_blocks.size() - 1;
std::size_t remaining = bitsPerBlock - div.rem;
for (std::size_t i = div.quot; i < lastIndex; ++i)
m_blocks[i - div.quot] = (m_blocks[i] >> div.rem) | (m_blocks[i + 1] << remaining);
m_blocks[lastIndex - div.quot] = m_blocks[lastIndex] >> div.rem;
std::fill_n(m_blocks.begin() + (m_blocks.size() - div.quot), div.quot, Block(0));
}
else
{
for (auto it = m_blocks.begin(); it != m_blocks.end(); ++it)
{
if (static_cast<std::size_t>(std::distance(m_blocks.begin(), it) + div.quot) < m_blocks.size())
{
auto shiftedIt = it;
std::advance(shiftedIt, div.quot);
*it = *shiftedIt;
}
else
*it = 0U;
}
}
ResetExtraBits();
}
/*! /*!
* \brief Swaps the two bitsets * \brief Swaps the two bitsets
* *
* \param bitset Other bitset to swap * \param bitset Other bitset to swap
*/ */
template<typename Block, class Allocator> template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Swap(Bitset& bitset) void Bitset<Block, Allocator>::Swap(Bitset& bitset)
{ {
@ -763,6 +870,80 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Shift all the bits toward the left
*
* \param pos Bit shifting to be applied
*
* \return A copies of the bitset with shifted bits
*
* \remark This does not changes the size of the bitset.
*
* \see ShiftLeft
*/
template<typename Block, class Allocator>
Bitset<Block, Allocator> Bitset<Block, Allocator>::operator<<(std::size_t pos) const
{
Bitset bitset(*this);
return bitset <<= pos;
}
/*!
* \brief Shift all the bits toward the left
*
* \param pos Bit shifting to be applied
*
* \return A reference to this
*
* \remark This does not changes the size of the bitset.
*
* \see ShiftLeft
*/
template<typename Block, class Allocator>
Bitset<Block, Allocator>& Bitset<Block, Allocator>::operator<<=(std::size_t pos)
{
ShiftLeft(pos);
return *this;
}
/*!
* \brief Shift all the bits toward the right
*
* \param pos Bit shifting to be applied
*
* \return A copies of the bitset with shifted bits
*
* \remark This does not changes the size of the bitset.
*
* \see ShiftRight
*/
template<typename Block, class Allocator>
Bitset<Block, Allocator> Bitset<Block, Allocator>::operator>>(std::size_t pos) const
{
Bitset bitset(*this);
return bitset >>= pos;
}
/*!
* \brief Shift all the bits toward the right
*
* \param pos Bit shifting to be applied
*
* \return A reference to this
*
* \remark This does not changes the size of the bitset.
*
* \see ShiftRight
*/
template<typename Block, class Allocator>
Bitset<Block, Allocator>& Bitset<Block, Allocator>::operator>>=(std::size_t pos)
{
ShiftRight(pos);
return *this;
}
/*! /*!
* \brief Performs an "AND" with another bitset * \brief Performs an "AND" with another bitset
* \return A reference to this * \return A reference to this

View File

@ -72,8 +72,8 @@
// Number of spinlocks to use with the Windows critical sections (0 to disable) // Number of spinlocks to use with the Windows critical sections (0 to disable)
#define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096 #define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096
// Optimize the Windows implementation with technologies of Windows vista (and greather) (Break the compatibility with XP) // Optimize the Windows implementation with technologies of Windows NT 6.0 (and greater) (Break the compatibility with Windows XP)
#define NAZARA_CORE_WINDOWS_VISTA 0 #define NAZARA_CORE_WINDOWS_NT6 0
/* /*

View File

@ -8,6 +8,7 @@
#define NAZARA_LOG_HPP #define NAZARA_LOG_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/AbstractLogger.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Signal.hpp> #include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/String.hpp> #include <Nazara/Core/String.hpp>
@ -29,8 +30,6 @@
namespace Nz namespace Nz
{ {
class AbstractLogger;
class NAZARA_CORE_API Log class NAZARA_CORE_API Log
{ {
friend class Core; friend class Core;

View File

@ -7,6 +7,27 @@
#ifndef NAZARA_MEMORYHELPER_HPP #ifndef NAZARA_MEMORYHELPER_HPP
#define NAZARA_MEMORYHELPER_HPP #define NAZARA_MEMORYHELPER_HPP
#if defined(NAZARA_COMPILER_MSVC) || defined(NAZARA_COMPILER_MINGW)
#include <malloc.h>
#define NAZARA_ALLOCA(size) _alloca(size)
#define NAZARA_ALLOCA_SUPPORT
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
#include <alloca.h>
#define NAZARA_ALLOCA(size) alloca(size)
#define NAZARA_ALLOCA_SUPPORT
#endif
#ifdef NAZARA_ALLOCA_SUPPORT
#define NazaraStackAllocation(size) Nz::StackAllocation(NAZARA_ALLOCA(size))
#else
#define NazaraStackAllocation(size) Nz::StackAllocation(Nz::OperatorNew(size))
#endif
#include <cstddef> #include <cstddef>
namespace Nz namespace Nz
@ -16,6 +37,20 @@ namespace Nz
template<typename T, typename... Args> template<typename T, typename... Args>
T* PlacementNew(T* ptr, Args&&... args); T* PlacementNew(T* ptr, Args&&... args);
class StackAllocation
{
public:
explicit StackAllocation(void* stackMemory);
~StackAllocation();
void* GetPtr();
operator void*();
private:
void* m_ptr;
};
} }
#include <Nazara/Core/MemoryHelper.inl> #include <Nazara/Core/MemoryHelper.inl>

View File

@ -9,6 +9,7 @@
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif #endif
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MemoryManager.hpp> #include <Nazara/Core/MemoryManager.hpp>
#include <new> #include <new>
#include <utility> #include <utility>
@ -62,6 +63,51 @@ namespace Nz
{ {
return new (ptr) T(std::forward<Args>(args)...); return new (ptr) T(std::forward<Args>(args)...);
} }
/*!
* \ingroup core
* \class Nz::StackAllocation
* \brief Core class that represents a stack allocation
*/
/*!
* \brief Constructs a StackAllocation object with a pointer to a memory allocated with NAZARA_ALLOCA or OperatorNew is alloca is not supported
*
* \param ptr Pointer to raw memory
*/
inline StackAllocation::StackAllocation(void* stackMemory) :
m_ptr(stackMemory)
{
}
/*!
* \brief Destructs the object and release memory if necessary
*/
inline StackAllocation::~StackAllocation()
{
#ifndef NAZARA_ALLOCA_SUPPORT
OperatorDelete(m_ptr);
#endif
}
/*!
* \brief Access the internal pointer
* \return internal memory pointer
*/
inline void* StackAllocation::GetPtr()
{
return m_ptr;
}
/*!
* \brief Access the internal pointer
* \return internal memory pointer
*/
inline StackAllocation::operator void*()
{
return m_ptr;
}
} }
#include <Nazara/Core/DebugOff.hpp> #include <Nazara/Core/DebugOff.hpp>

View File

@ -1,4 +1,4 @@
// This file was automatically generated on 20 Jul 2016 at 13:49:17 // This file was automatically generated on 15 Sep 2016 at 00:43:26
/* /*
Nazara Engine - Graphics module Nazara Engine - Graphics module
@ -58,10 +58,14 @@
#include <Nazara/Graphics/InstancedRenderable.hpp> #include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Graphics/Light.hpp> #include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPipeline.hpp>
#include <Nazara/Graphics/Model.hpp> #include <Nazara/Graphics/Model.hpp>
#include <Nazara/Graphics/ParticleController.hpp> #include <Nazara/Graphics/ParticleController.hpp>
#include <Nazara/Graphics/ParticleDeclaration.hpp> #include <Nazara/Graphics/ParticleDeclaration.hpp>
#include <Nazara/Graphics/ParticleEmitter.hpp> #include <Nazara/Graphics/ParticleEmitter.hpp>
#include <Nazara/Graphics/ParticleFunctionController.hpp>
#include <Nazara/Graphics/ParticleFunctionGenerator.hpp>
#include <Nazara/Graphics/ParticleFunctionRenderer.hpp>
#include <Nazara/Graphics/ParticleGenerator.hpp> #include <Nazara/Graphics/ParticleGenerator.hpp>
#include <Nazara/Graphics/ParticleGroup.hpp> #include <Nazara/Graphics/ParticleGroup.hpp>
#include <Nazara/Graphics/ParticleMapper.hpp> #include <Nazara/Graphics/ParticleMapper.hpp>
@ -77,5 +81,6 @@
#include <Nazara/Graphics/Sprite.hpp> #include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Graphics/TextSprite.hpp> #include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Graphics/TextureBackground.hpp> #include <Nazara/Graphics/TextureBackground.hpp>
#include <Nazara/Graphics/TileMap.hpp>
#endif // NAZARA_GLOBAL_GRAPHICS_HPP #endif // NAZARA_GLOBAL_GRAPHICS_HPP

View File

@ -38,19 +38,25 @@ namespace Nz
shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor));
shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction));
shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); if (uniforms.locations.shadowMapping != -1)
shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr);
if (light.shadowMap) if (light.shadowMap)
{ {
Renderer::SetTexture(availableTextureUnit, light.shadowMap); Renderer::SetTexture(availableTextureUnit, light.shadowMap);
Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler);
shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); if (uniforms.locations.lightViewProjMatrix != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix);
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit);
} }
else else if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
break; break;
} }
@ -63,18 +69,22 @@ namespace Nz
shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); 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)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius));
shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); if (uniforms.locations.shadowMapping != -1)
shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr);
if (light.shadowMap) if (light.shadowMap)
{ {
Renderer::SetTexture(availableTextureUnit, light.shadowMap); Renderer::SetTexture(availableTextureUnit, light.shadowMap);
Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler);
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit); if (uniforms.locations.pointLightShadowMap != -1)
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit);
} }
else else if (uniforms.locations.pointLightShadowMap != -1)
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
break; break;
} }
@ -88,19 +98,25 @@ namespace Nz
shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius));
shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine));
shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); if (uniforms.locations.shadowMapping != -1)
shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr);
if (light.shadowMap) if (light.shadowMap)
{ {
Renderer::SetTexture(availableTextureUnit, light.shadowMap); Renderer::SetTexture(availableTextureUnit, light.shadowMap);
Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler);
shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); if (uniforms.locations.lightViewProjMatrix != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix);
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit);
} }
else else if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); if (uniforms.locations.pointLightShadowMap != -1)
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
break; break;
} }
@ -108,9 +124,14 @@ namespace Nz
} }
else else
{ {
shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader if (uniforms.locations.type != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
if (uniforms.locations.pointLightShadowMap != -1)
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
} }
} }

View File

@ -17,6 +17,7 @@ namespace Nz
struct ParticleStruct_Billboard struct ParticleStruct_Billboard
{ {
Color color; Color color;
Vector2f size;
Vector3f normal; Vector3f normal;
Vector3f position; Vector3f position;
Vector3f velocity; Vector3f velocity;

View File

@ -41,6 +41,8 @@ namespace Nz
inline void DisableTiles(); inline void DisableTiles();
inline void DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount); inline void DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount);
inline void EnableIsometricMode(bool isometric);
inline void EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); inline void EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U);
inline void EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U); inline void EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U);
inline void EnableTiles(const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); inline void EnableTiles(const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U);
@ -55,6 +57,8 @@ namespace Nz
inline const Tile& GetTile(const Vector2ui& tilePos) const; inline const Tile& GetTile(const Vector2ui& tilePos) const;
inline const Vector2f& GetTileSize() const; inline const Vector2f& GetTileSize() const;
inline bool IsIsometricModeEnabled() const;
inline void SetMaterial(std::size_t index, MaterialRef material); inline void SetMaterial(std::size_t index, MaterialRef material);
inline TileMap& operator=(const TileMap& TileMap); inline TileMap& operator=(const TileMap& TileMap);
@ -87,6 +91,7 @@ namespace Nz
std::vector<Layer> m_layers; std::vector<Layer> m_layers;
Vector2ui m_mapSize; Vector2ui m_mapSize;
Vector2f m_tileSize; Vector2f m_tileSize;
bool m_isometricModeEnabled;
static TileMapLibrary::LibraryMap s_library; static TileMapLibrary::LibraryMap s_library;
}; };

View File

@ -25,7 +25,8 @@ namespace Nz
m_tiles(mapSize.x * mapSize.y), m_tiles(mapSize.x * mapSize.y),
m_layers(materialCount), m_layers(materialCount),
m_mapSize(mapSize), m_mapSize(mapSize),
m_tileSize(tileSize) m_tileSize(tileSize),
m_isometricModeEnabled(false)
{ {
NazaraAssert(m_tiles.size() != 0U, "Invalid map size"); NazaraAssert(m_tiles.size() != 0U, "Invalid map size");
NazaraAssert(m_tileSize.x != 0U && m_tileSize.y != 0U, "Invalid tile size"); NazaraAssert(m_tileSize.x != 0U && m_tileSize.y != 0U, "Invalid tile size");
@ -108,6 +109,22 @@ namespace Nz
InvalidateInstanceData(invalidatedLayers); InvalidateInstanceData(invalidatedLayers);
} }
/*!
* \brief Enable/Disable isometric mode
*
* If enabled, every odd line will overlap by half the tile size with the upper line
*
* \param isometric Should the isometric mode be enabled for this TileMap
*
* \see IsIsometricModeEnabled
*/
inline void TileMap::EnableIsometricMode(bool isometric)
{
m_isometricModeEnabled = isometric;
InvalidateInstanceData(0xFFFFFFFF);
}
/*! /*!
* \brief Enable and sets the tile at position tilePos * \brief Enable and sets the tile at position tilePos
* *
@ -387,6 +404,17 @@ namespace Nz
return m_tileSize; return m_tileSize;
} }
/*!
* \brief Gets the actual state of the isometric mode
* \return True if the isometric mode is enabled
*
* \see EnableIsometricMode
*/
inline bool TileMap::IsIsometricModeEnabled() const
{
return m_isometricModeEnabled;
}
/*! /*!
* \brief Sets a material of the TileMap * \brief Sets a material of the TileMap
* *

View File

@ -28,7 +28,7 @@ namespace Nz
public: public:
using ClassFunc = std::function<int(LuaInstance& lua, T& instance)>; using ClassFunc = std::function<int(LuaInstance& lua, T& instance)>;
using ClassIndexFunc = std::function<bool(LuaInstance& lua, T& instance)>; using ClassIndexFunc = std::function<bool(LuaInstance& lua, T& instance)>;
using ConstructorFunc = std::function<bool(LuaInstance& lua, T* instance)>; using ConstructorFunc = std::function<bool(LuaInstance& lua, T* instance, std::size_t argumentCount)>;
template<typename P> using ConvertToParent = std::function<P*(T*)>; template<typename P> using ConvertToParent = std::function<P*(T*)>;
using FinalizerFunc = std::function<bool(LuaInstance& lua, T& instance)>; using FinalizerFunc = std::function<bool(LuaInstance& lua, T& instance)>;
using StaticIndexFunc = std::function<bool(LuaInstance& lua)>; using StaticIndexFunc = std::function<bool(LuaInstance& lua)>;

View File

@ -19,9 +19,10 @@ namespace Nz
template<class T> template<class T>
inline void LuaClass<T>::BindDefaultConstructor() inline void LuaClass<T>::BindDefaultConstructor()
{ {
SetConstructor([] (Nz::LuaInstance& lua, T* instance) SetConstructor([] (Nz::LuaInstance& lua, T* instance, std::size_t argumentCount)
{ {
NazaraUnused(lua); NazaraUnused(lua);
NazaraUnused(argumentCount);
PlacementNew(instance); PlacementNew(instance);
return true; return true;
@ -334,9 +335,11 @@ namespace Nz
lua.Remove(1); // On enlève l'argument "table" du stack lua.Remove(1); // On enlève l'argument "table" du stack
std::size_t argCount = lua.GetStackTop();
T* instance = static_cast<T*>(lua.PushUserdata(sizeof(T))); T* instance = static_cast<T*>(lua.PushUserdata(sizeof(T)));
if (!constructor(lua, instance)) if (!constructor(lua, instance, argCount))
{ {
lua.Error("Constructor failed"); lua.Error("Constructor failed");
return 0; // Normalement jamais exécuté (l'erreur provoquant une exception) return 0; // Normalement jamais exécuté (l'erreur provoquant une exception)

View File

@ -16,11 +16,11 @@ namespace Nz
inline LuaInstance::LuaInstance(LuaInstance&& instance) noexcept : inline LuaInstance::LuaInstance(LuaInstance&& instance) noexcept :
m_memoryLimit(instance.m_memoryLimit), m_memoryLimit(instance.m_memoryLimit),
m_memoryUsage(instance.m_memoryUsage), m_memoryUsage(instance.m_memoryUsage),
m_timeLimit(m_timeLimit), m_timeLimit(instance.m_timeLimit),
m_clock(std::move(m_clock)), m_clock(std::move(instance.m_clock)),
m_lastError(std::move(m_lastError)), m_lastError(std::move(instance.m_lastError)),
m_state(m_state), m_state(instance.m_state),
m_level(m_level) m_level(instance.m_level)
{ {
instance.m_state = nullptr; instance.m_state = nullptr;
} }
@ -52,13 +52,13 @@ namespace Nz
inline LuaInstance& LuaInstance::operator=(LuaInstance&& instance) noexcept inline LuaInstance& LuaInstance::operator=(LuaInstance&& instance) noexcept
{ {
m_clock = std::move(m_clock); m_clock = std::move(instance.m_clock);
m_lastError = std::move(m_lastError); m_lastError = std::move(instance.m_lastError);
m_level = m_level; m_level = instance.m_level;
m_memoryLimit = instance.m_memoryLimit; m_memoryLimit = instance.m_memoryLimit;
m_memoryUsage = instance.m_memoryUsage; m_memoryUsage = instance.m_memoryUsage;
m_state = m_state; m_state = instance.m_state;
m_timeLimit = m_timeLimit; m_timeLimit = instance.m_timeLimit;
instance.m_state = nullptr; instance.m_state = nullptr;

View File

@ -0,0 +1,44 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLER_HPP
#define NAZARA_SOCKETPOLLER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Network/AbstractSocket.hpp>
#include <Nazara/Network/IpAddress.hpp>
namespace Nz
{
class SocketPollerImpl;
class NAZARA_NETWORK_API SocketPoller
{
public:
SocketPoller();
inline SocketPoller(SocketPoller&& socketPoller);
~SocketPoller();
void Clear();
bool IsReady(const AbstractSocket& socket) const;
bool IsRegistered(const AbstractSocket& socket) const;
bool RegisterSocket(AbstractSocket& socket);
void UnregisterSocket(AbstractSocket& socket);
bool Wait(UInt64 msTimeout);
inline SocketPoller& operator=(SocketPoller&& socketPoller);
private:
SocketPollerImpl* m_impl;
};
}
#include <Nazara/Network/SocketPoller.inl>
#endif // NAZARA_SOCKETPOLLER_HPP

View File

@ -0,0 +1,37 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/SocketPoller.hpp>
#include <utility>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
/*!
* \brief Constructs a SocketPoller object with another one by move semantic
*
* \param socketPoller SocketPoller to move into this
*/
inline SocketPoller::SocketPoller(SocketPoller&& socketPoller) :
m_impl(socketPoller.m_impl)
{
socketPoller.m_impl = nullptr;
}
/*!
* \brief Moves the SocketPoller into this
* \return A reference to this
*
* \param socketPoller SocketPoller to move in this
*/
inline SocketPoller& SocketPoller::operator=(SocketPoller&& socketPoller)
{
m_impl = socketPoller.m_impl;
socketPoller.m_impl = nullptr;
return *this;
}
}
#include <Nazara/Network/DebugOff.hpp>

View File

@ -2,8 +2,8 @@
// This file is part of the "Nazara Engine - Noise module" // This file is part of the "Nazara Engine - Noise module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#ifndef SIMPLEX_HPP #ifndef NAZARA_SIMPLEX_HPP
#define SIMPLE_HPP #define NAZARA_SIMPLEX_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Noise/Config.hpp> #include <Nazara/Noise/Config.hpp>
@ -25,4 +25,4 @@ namespace Nz
}; };
} }
#endif // SIMPLEX_HPP #endif // NAZARA_SIMPLEX_HPP

View File

@ -74,9 +74,10 @@
#error Nazara requires a C++11 compliant compiler #error Nazara requires a C++11 compliant compiler
#endif #endif
// Version du moteur // Nazara version macro
#define NAZARA_VERSION_MAJOR 0 #define NAZARA_VERSION_MAJOR 0
#define NAZARA_VERSION_MINOR 1 #define NAZARA_VERSION_MINOR 1
#define NAZARA_VERSION_PATCH 1
#include <Nazara/Core/Config.hpp> #include <Nazara/Core/Config.hpp>
@ -97,7 +98,7 @@
#define NOMINMAX #define NOMINMAX
#endif #endif
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
// Version de Windows minimale : Vista // Version de Windows minimale : Vista
#define NAZARA_WINNT 0x0600 #define NAZARA_WINNT 0x0600
#else #else

View File

@ -0,0 +1,82 @@
// Copyright (C) 2015 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_RENDERSTATES_HPP
#define NAZARA_RENDERSTATES_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/Enums.hpp>
namespace Nz
{
struct RenderStates
{
BlendFunc dstBlend = BlendFunc_Zero;
BlendFunc srcBlend = BlendFunc_One;
FaceFilling faceFilling = FaceFilling_Fill;
FaceSide cullingSide = FaceSide_Back;
RendererComparison depthFunc = RendererComparison_Less;
struct
{
RendererComparison back = RendererComparison_Always;
RendererComparison front = RendererComparison_Always;
} stencilCompare;
struct
{
UInt32 back = 0xFFFFFFFF;
UInt32 front = 0xFFFFFFFF;
} stencilCompareMask;
struct
{
StencilOperation back = StencilOperation_Keep;
StencilOperation front = StencilOperation_Keep;
} stencilDepthFail;
struct
{
StencilOperation back = StencilOperation_Keep;
StencilOperation front = StencilOperation_Keep;
} stencilFail;
struct
{
StencilOperation back = StencilOperation_Keep;
StencilOperation front = StencilOperation_Keep;
} stencilPass;
struct
{
UInt32 back = 0U;
UInt32 front = 0U;
} stencilReference;
struct
{
UInt32 back = 0xFFFFFFFF;
UInt32 front = 0xFFFFFFFF;
} stencilWriteMask;
bool blending = false;
bool colorWrite = true;
bool depthBuffer = false;
bool depthWrite = true;
bool faceCulling = false;
bool scissorTest = false;
bool stencilTest = false;
float lineWidth = 1.f;
float pointSize = 1.f;
};
inline bool operator==(const RenderStates& lhs, const RenderStates& rhs);
}
#include <Nazara/Renderer/RenderStates.inl>
#endif // NAZARA_RENDERSTATES_HPP

View File

@ -0,0 +1,145 @@
// Copyright (C) 2015 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 <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <functional>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
bool operator==(const RenderStates& lhs, const RenderStates& rhs)
{
#define NazaraRenderStateMember(field) if (lhs.field != rhs.field) return false
#define NazaraRenderStateBoolMember NazaraRenderStateMember
#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.field, rhs.field, maxDiff)) return false
NazaraRenderStateBoolMember(blending);
NazaraRenderStateBoolMember(colorWrite);
NazaraRenderStateBoolMember(depthBuffer);
NazaraRenderStateBoolMember(faceCulling);
NazaraRenderStateBoolMember(scissorTest);
NazaraRenderStateBoolMember(stencilTest);
if (lhs.depthBuffer)
NazaraRenderStateBoolMember(depthWrite);
NazaraRenderStateMember(faceFilling);
if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
{
NazaraRenderStateMember(dstBlend);
NazaraRenderStateMember(srcBlend);
}
if (lhs.depthBuffer)
NazaraRenderStateMember(depthFunc);
if (lhs.faceCulling)
NazaraRenderStateMember(cullingSide);
if (lhs.stencilTest)
{
NazaraRenderStateMember(stencilCompare.back);
NazaraRenderStateMember(stencilCompare.front);
NazaraRenderStateMember(stencilCompareMask.back);
NazaraRenderStateMember(stencilCompareMask.front);
NazaraRenderStateMember(stencilDepthFail.back);
NazaraRenderStateMember(stencilDepthFail.front);
NazaraRenderStateMember(stencilFail.back);
NazaraRenderStateMember(stencilFail.front);
NazaraRenderStateMember(stencilPass.back);
NazaraRenderStateMember(stencilPass.front);
NazaraRenderStateMember(stencilReference.back);
NazaraRenderStateMember(stencilReference.front);
NazaraRenderStateMember(stencilWriteMask.back);
NazaraRenderStateMember(stencilWriteMask.front);
}
NazaraRenderStateFloatMember(lineWidth, 0.001f);
NazaraRenderStateFloatMember(pointSize, 0.001f);
#undef NazaraRenderStateMember
#undef NazaraRenderStateBoolMember
#undef NazaraRenderStateFloatMember
return true;
}
}
namespace std
{
template<>
struct hash<Nz::RenderStates>
{
size_t operator()(const Nz::RenderStates& pipelineInfo) const
{
std::size_t seed = 0;
Nz::UInt8 parameterHash = 0;
Nz::UInt8 parameterIndex = 0;
#define NazaraRenderStateBool(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
#define NazaraRenderStateBoolDep(dependency, member) parameterHash |= ((pipelineInfo.dependency && pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
#define NazaraRenderStateEnum(member) Nz::HashCombine(seed, static_cast<Nz::UInt8>(pipelineInfo.member))
#define NazaraRenderStateFloat(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.member / maxDiff) * maxDiff)
NazaraRenderStateBool(blending);
NazaraRenderStateBool(colorWrite);
NazaraRenderStateBool(depthBuffer);
NazaraRenderStateBool(faceCulling);
NazaraRenderStateBool(scissorTest);
NazaraRenderStateBool(stencilTest);
NazaraRenderStateBoolDep(depthBuffer, depthWrite);
NazaraRenderStateEnum(faceFilling);
if (pipelineInfo.blending) //< Remember, at this time we know lhs.blending == rhs.blending
{
NazaraRenderStateEnum(dstBlend);
NazaraRenderStateEnum(srcBlend);
}
if (pipelineInfo.depthBuffer)
NazaraRenderStateEnum(depthFunc);
if (pipelineInfo.faceCulling)
NazaraRenderStateEnum(cullingSide);
if (pipelineInfo.stencilTest)
{
NazaraRenderStateEnum(stencilCompare.back);
NazaraRenderStateEnum(stencilCompare.front);
NazaraRenderStateEnum(stencilCompareMask.back);
NazaraRenderStateEnum(stencilCompareMask.front);
NazaraRenderStateEnum(stencilDepthFail.back);
NazaraRenderStateEnum(stencilDepthFail.front);
NazaraRenderStateEnum(stencilFail.back);
NazaraRenderStateEnum(stencilFail.front);
NazaraRenderStateEnum(stencilPass.back);
NazaraRenderStateEnum(stencilPass.front);
NazaraRenderStateEnum(stencilReference.back);
NazaraRenderStateEnum(stencilReference.front);
NazaraRenderStateEnum(stencilWriteMask.back);
NazaraRenderStateEnum(stencilWriteMask.front);
}
NazaraRenderStateFloat(lineWidth, 0.001f);
NazaraRenderStateFloat(pointSize, 0.001f);
#undef NazaraRenderStateBool
#undef NazaraRenderStateBoolDep
#undef NazaraRenderStateEnum
#undef NazaraRenderStateFloat
Nz::HashCombine(seed, parameterHash);
return seed;
}
};
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@ -29,6 +29,8 @@ namespace Nz
inline void Clear(); inline void Clear();
bool Check(Stream& stream);
inline String* GetMaterials(); inline String* GetMaterials();
inline const String* GetMaterials() const; inline const String* GetMaterials() const;
inline UInt32 GetMaterialCount() const; inline UInt32 GetMaterialCount() const;

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Initializer.hpp> #include <Nazara/Core/Initializer.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Utility/Config.hpp> #include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Enums.hpp> #include <Nazara/Utility/Enums.hpp>
@ -24,12 +25,15 @@ namespace Nz
static bool IsInitialized(); static bool IsInitialized();
static void SetParameters(const ParameterList& parameters);
static void Uninitialize(); static void Uninitialize();
static unsigned int ComponentCount[ComponentType_Max+1]; static unsigned int ComponentCount[ComponentType_Max+1];
static std::size_t ComponentStride[ComponentType_Max+1]; static std::size_t ComponentStride[ComponentType_Max+1];
private: private:
static ParameterList s_initializationParameters;
static unsigned int s_moduleReferenceCounter; static unsigned int s_moduleReferenceCounter;
}; };
} }

View File

@ -55,11 +55,6 @@ namespace Nz
window.m_impl = nullptr; window.m_impl = nullptr;
} }
inline Window::~Window()
{
Destroy();
}
inline void Window::Close() inline void Window::Close()
{ {
m_closed = true; // The window will be closed at the next non-const IsOpen() call m_closed = true; // The window will be closed at the next non-const IsOpen() call

View File

@ -1,5 +1,9 @@
Nazara Engine Platform | Build Status
============= ------------ | -------------
Windows | [![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/dj5qx7axym4uakmy/branch/master?svg=true)](https://ci.appveyor.com/project/DPSLynix/nazaraengine/branch/master)
Linux | [![Travis CI Build Status](https://travis-ci.org/DigitalPulseSoftware/NazaraEngine.svg)](https://travis-ci.org/DigitalPulseSoftware/NazaraEngine)
# Nazara Engine
Nazara Engine is a fast, complete, cross-platform, object-oriented API which can help you in your daily developper life. Nazara Engine is a fast, complete, cross-platform, object-oriented API which can help you in your daily developper life.
Its goal is to provide a set of useful classes : Its core provides unicode strings, filesystem access, hashs, threads, ... Its goal is to provide a set of useful classes : Its core provides unicode strings, filesystem access, hashs, threads, ...
@ -8,26 +12,22 @@ It also provide a set of libraries, such as audio, network, physics, renderer, 2
You can use it in any kind of commercial/non-commercial applications without any restriction ([MIT license](http://opensource.org/licenses/MIT)). You can use it in any kind of commercial/non-commercial applications without any restriction ([MIT license](http://opensource.org/licenses/MIT)).
Authors ## Authors
-------
Jérôme "Lynix" Leclercq - main developper (<lynix680@gmail.com>) Jérôme "Lynix" Leclercq - main developper (<lynix680@gmail.com>)
Rémi "overdrivr" Bèges - developper & helper - Noise Module - (<remi.beges@laposte.net>) Rémi "overdrivr" Bèges - developper & helper - Noise Module - (<remi.beges@laposte.net>)
Install ## Install
-------
Use the premake build system in the build directory then compile the engine for your platform. Use the premake build system in the build directory then compile the engine for your platform.
How to use ## How to use
----------
You can find tutorials on installation, compilation and use on the [official wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) You can find tutorials on installation, compilation and use on the [official wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki)
Contribute ## Contribute
----------
#####Don't hesitate to contribute to Nazara Engine by:##### ##### Don't hesitate to contribute to Nazara Engine by:
- Extending the [wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) - Extending the [wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki)
- Submitting a patch to GitHub - Submitting a patch to GitHub
- Post suggestions/bugs on the forum or the [GitHub tracker](https://github.com/DigitalPulseSoftware/NazaraEngine/issues) - Post suggestions/bugs on the forum or the [GitHub tracker](https://github.com/DigitalPulseSoftware/NazaraEngine/issues)
@ -35,14 +35,17 @@ Contribute
- Talking about Nazara Engine to other people - Talking about Nazara Engine to other people
- Doing anything else that might help us - Doing anything else that might help us
Links ## Links
-----
[Website](http://www.digitalpulsesoftware.net) [Website](https://nazara.digitalpulsesoftware.net)
[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) [Documentation](https://nazara.digitalpulsesoftware.net/doc)
[Forum](http://forum.digitalpulsesoftware.net) [Mattermost](https://mattermost.digitalpulsesoftware.net)
[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki)
[Forum](https://forum.digitalpulsesoftware.net)
## Thanks to:
###Thanks to:###
- **RafBill** and **Raakz:** Finding bugs and/or testing - **RafBill** and **Raakz:** Finding bugs and/or testing
- **Fissal "DrFisher" Hannoun**: Helping a lot in architecture design - **Fissal "DrFisher" Hannoun**: Helping a lot in architecture design
- **Alexandre "Danman" Janniaux**: Helping making the POSIX implementation - **Alexandre "Danman" Janniaux**: Helping making the POSIX implementation
- **Youri "Gawaboumga" Hubaut**: Improving the engine code by merging on GitHub - **Youri "Gawaboumga" Hubaut**: Improving the whole project by making the documentation, improving the code, and more.

View File

@ -1,5 +1,9 @@
Nazara Engine Platforme | Build Status
============= ------------ | -------------
Windows | [![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/dj5qx7axym4uakmy/branch/master?svg=true)](https://ci.appveyor.com/project/DPSLynix/nazaraengine/branch/master)
Linux | [![Travis CI Build Status](https://travis-ci.org/DigitalPulseSoftware/NazaraEngine.svg)](https://travis-ci.org/DigitalPulseSoftware/NazaraEngine)
# Nazara Engine
Nazara Engine est une API rapide, complète, portable et orientée-objet qui peut vous aider dans votre vie de développeur de tous les jours. Nazara Engine est une API rapide, complète, portable et orientée-objet qui peut vous aider dans votre vie de développeur de tous les jours.
Son objectif est de fournir un ensemble de classes utiles : Son noyau dispose de chaînes de caractères unicode, de gestion du système de fichiers, hashs, threads, ... Son objectif est de fournir un ensemble de classes utiles : Son noyau dispose de chaînes de caractères unicode, de gestion du système de fichiers, hashs, threads, ...
@ -8,26 +12,22 @@ Il propose aussi un ensemble de bibliothèques, comme audio, réseau, physique,
Vous pouvez également l'utiliser pour toute application commerciale sans aucune contrainte ([Licence MIT](http://opensource.org/licenses/MIT)). Vous pouvez également l'utiliser pour toute application commerciale sans aucune contrainte ([Licence MIT](http://opensource.org/licenses/MIT)).
Auteurs ## Auteurs
-------
Jérôme "Lynix" Leclercq - développeur principal (<lynix680@gmail.com>) Jérôme "Lynix" Leclercq - développeur principal (<lynix680@gmail.com>)
Rémi "overdrivr" Bèges - développeur & aide - module Noise - (<remi.beges@laposte.net>) Rémi "overdrivr" Bèges - développeur & aide - module Noise - (<remi.beges@laposte.net>)
Installation ## Installation
------------
Utilisez le système premake pour construire le projet du moteur, dans le dossier build, pour ensuite compiler le moteur pour votre plateforme. Utilisez le système premake pour construire le projet du moteur, dans le dossier build, pour ensuite compiler le moteur pour votre plateforme.
Utilisation ## Utilisation
-----------
Vous pouvez lire des tutoriaux sur l'installation, la compilation et l'utilisation sur le [wiki officiel](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) (**\*En cours de rédaction***) Vous pouvez lire des tutoriaux sur l'installation, la compilation et l'utilisation sur le [wiki officiel](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) (**\*En cours de rédaction***)
Contribution ## Contribution
----------
#####N'hésitez pas à contribuer à Nazara Engine en :##### ##### N'hésitez pas à contribuer à Nazara Engine en :
- Contribuant au [wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) (**\*Lien brisé***) - Contribuant au [wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) (**\*Lien brisé***)
- Soumettant un patch sur GitHub - Soumettant un patch sur GitHub
- Postant des suggestions/bugs sur le forum ou sur le [tracker GitHub](https://github.com/DigitalPulseSoftware/NazaraEngine/issues) - Postant des suggestions/bugs sur le forum ou sur le [tracker GitHub](https://github.com/DigitalPulseSoftware/NazaraEngine/issues)
@ -35,14 +35,17 @@ Contribution
- Parlant du Nazara Engine à d'autres personnes - Parlant du Nazara Engine à d'autres personnes
- Faisant n'importe quoi d'autre qui pourrait nous aider - Faisant n'importe quoi d'autre qui pourrait nous aider
Liens ## Liens
-----
[Website](http://www.digitalpulsesoftware.net) [Website](https://nazara.digitalpulsesoftware.net)
[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki) [Documentation](https://nazara.digitalpulsesoftware.net/doc)
[Forum](http://forum.digitalpulsesoftware.net) [Mattermost](https://mattermost.digitalpulsesoftware.net)
[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki)
[Forum](https://forum.digitalpulsesoftware.net)
###Remerciements:
###Remerciements:###
- **RafBill** et **Raakz:** Recherche de bugs et/ou tests - **RafBill** et **Raakz:** Recherche de bugs et/ou tests
- **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur - **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur
- **Alexandre "Danman" Janniaux**: Aide sur l'implémentation POSIX - **Alexandre "Danman" Janniaux**: Aide sur l'implémentation POSIX
- **Youri "Gawaboumga" Hubaut**: Amélioration du code via le merging sur GitHub - **Youri "Gawaboumga" Hubaut**: Amélioration du moteur tant au niveau du code que de sa documentation et du projet en général.

View File

@ -11,10 +11,22 @@ namespace Nz
void HardwareInfoImpl::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4]) void HardwareInfoImpl::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4])
{ {
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) #if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c // https://en.wikipedia.org/wiki/CPUID
asm volatile ("cpuid" // Besoin d'être volatile ? asm volatile(
: "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output #ifdef NAZARA_PLATFORM_x64
: "a" (functionId), "c" (subFunctionId)); // input "pushq %%rbx \n\t" // save %rbx
#else
"pushl %%ebx \n\t" // save %ebx
#endif
"cpuid \n\t"
"movl %%ebx ,%[ebx] \n\t" // write the result into output var
#ifdef NAZARA_PLATFORM_x64
"popq %%rbx \n\t"
#else
"popl %%ebx \n\t"
#endif
: "=a"(registers[0]), [ebx] "=r"(registers[1]), "=c"(registers[2]), "=d"(registers[3])
: "a"(functionId), "c" (subFunctionId));
#else #else
NazaraInternalError("Cpuid has been called although it is not supported"); NazaraInternalError("Cpuid has been called although it is not supported");
#endif #endif
@ -22,7 +34,7 @@ namespace Nz
unsigned int HardwareInfoImpl::GetProcessorCount() unsigned int HardwareInfoImpl::GetProcessorCount()
{ {
// Plus simple (et plus portable) que de passer par le CPUID // Simpler (and more portable) than using CPUID
return sysconf(_SC_NPROCESSORS_CONF); return sysconf(_SC_NPROCESSORS_CONF);
} }
@ -37,7 +49,7 @@ namespace Nz
bool HardwareInfoImpl::IsCpuidSupported() bool HardwareInfoImpl::IsCpuidSupported()
{ {
#ifdef NAZARA_PLATFORM_x64 #ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits return true; // cpuid is always supported on x64 arch
#else #else
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) #if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
int supported; int supported;

View File

@ -44,14 +44,19 @@ namespace Nz
} }
/*! /*!
* \brief Reads characters in the stream * \brief Reads a line from the stream
*
* Reads the stream until a line separator or the end of the stream is found.
*
* If lineSize does not equal zero, it represents the maximum character count to be read from the stream.
*
* \param lineSize Maximum number of characters to read, or zero for no limit
*
* \return Line containing characters * \return Line containing characters
* *
* \param lineSize Number of characters to read, if lineSize is 0, read as much as possible * \remark With the text stream option, "\r\n" is treated as "\n"
* * \remark The line separator character is not returned as part of the string
* \remark Produces a NazaraWarning if cursor position could not be reset
*/ */
String Stream::ReadLine(unsigned int lineSize) String Stream::ReadLine(unsigned int lineSize)
{ {
String line; String line;
@ -71,19 +76,33 @@ namespace Nz
if (ptr) if (ptr)
{ {
std::ptrdiff_t pos = ptr - buffer; std::ptrdiff_t pos = ptr - buffer;
if (ptr != buffer)
if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos - 1] == '\r') {
line.Append(buffer, pos - 1); if (m_streamOptions & StreamOption_Text && buffer[pos - 1] == '\r')
else line.Append(buffer, pos - 1);
line.Append(buffer, pos); else
line.Append(buffer, pos);
}
if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) if (!SetCursorPos(GetCursorPos() - readSize + pos + 1))
NazaraWarning("Failed to reset cursos pos"); NazaraWarning("Failed to reset cursor pos");
break; if (!line.IsEmpty())
break;
} }
else else
line.Append(buffer, readSize); {
std::size_t length = readSize;
if (m_streamOptions & StreamOption_Text && buffer[length - 1] == '\r')
{
if (!SetCursorPos(GetCursorPos() - 1))
NazaraWarning("Failed to reset cursor pos");
length--;
}
line.Append(buffer, length);
}
} }
while (readSize == bufferSize); while (readSize == bufferSize);
} }

View File

@ -3461,6 +3461,7 @@ namespace Nz
p--; p--;
*p = '\0'; *p = '\0';
newString->size = p - str;
return String(std::move(newString)); return String(std::move(newString));
} }
@ -4552,7 +4553,7 @@ namespace Nz
String& String::operator=(String&& string) noexcept String& String::operator=(String&& string) noexcept
{ {
return Set(string); return Set(std::move(string));
} }
/*! /*!
@ -5851,7 +5852,7 @@ namespace Nz
if (!m_sharedString.unique()) if (!m_sharedString.unique())
{ {
auto newSharedString = std::make_shared<SharedString>(GetSize(), GetCapacity()); auto newSharedString = std::make_shared<SharedString>(GetSize(), GetCapacity());
if (!discardContent) if (!discardContent && newSharedString->size > 0)
std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()+1); std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()+1);
m_sharedString = std::move(newSharedString); m_sharedString = std::move(newSharedString);
@ -5878,7 +5879,7 @@ namespace Nz
*/ */
bool Serialize(SerializationContext& context, const String& string) bool Serialize(SerializationContext& context, const String& string)
{ {
if (!Serialize<UInt32>(context, string.GetSize())) if (!Serialize(context, UInt32(string.GetSize())))
return false; return false;
return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize(); return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize();

View File

@ -12,7 +12,7 @@ namespace Nz
{ {
ConditionVariableImpl::ConditionVariableImpl() ConditionVariableImpl::ConditionVariableImpl()
{ {
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
InitializeConditionVariable(&m_cv); InitializeConditionVariable(&m_cv);
#else #else
m_count = 0; m_count = 0;
@ -21,7 +21,7 @@ namespace Nz
#endif #endif
} }
#if !NAZARA_CORE_WINDOWS_VISTA #if !NAZARA_CORE_WINDOWS_NT6
ConditionVariableImpl::~ConditionVariableImpl() ConditionVariableImpl::~ConditionVariableImpl()
{ {
CloseHandle(m_events[BROADCAST]); CloseHandle(m_events[BROADCAST]);
@ -31,7 +31,7 @@ namespace Nz
void ConditionVariableImpl::Signal() void ConditionVariableImpl::Signal()
{ {
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
WakeConditionVariable(&m_cv); WakeConditionVariable(&m_cv);
#else #else
if (m_count > 0) if (m_count > 0)
@ -41,7 +41,7 @@ namespace Nz
void ConditionVariableImpl::SignalAll() void ConditionVariableImpl::SignalAll()
{ {
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
WakeAllConditionVariable(&m_cv); WakeAllConditionVariable(&m_cv);
#else #else
if (m_count > 0) if (m_count > 0)
@ -56,8 +56,8 @@ namespace Nz
bool ConditionVariableImpl::Wait(MutexImpl* mutex, UInt32 timeout) bool ConditionVariableImpl::Wait(MutexImpl* mutex, UInt32 timeout)
{ {
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
return SleepConditionVariableCS(&m_cv, &mutex->m_criticalSection, timeout); return SleepConditionVariableCS(&m_cv, &mutex->m_criticalSection, timeout) == TRUE;
#else #else
m_count++; m_count++;

View File

@ -21,7 +21,7 @@ namespace Nz
{ {
public: public:
ConditionVariableImpl(); ConditionVariableImpl();
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
~ConditionVariableImpl() = default; ~ConditionVariableImpl() = default;
#else #else
~ConditionVariableImpl(); ~ConditionVariableImpl();
@ -34,7 +34,7 @@ namespace Nz
bool Wait(MutexImpl* mutex, UInt32 timeout); bool Wait(MutexImpl* mutex, UInt32 timeout);
private: private:
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
CONDITION_VARIABLE m_cv; CONDITION_VARIABLE m_cv;
#else #else
enum enum

View File

@ -22,10 +22,22 @@ namespace Nz
// Visual propose une fonction intrinsèque pour le cpuid // Visual propose une fonction intrinsèque pour le cpuid
__cpuidex(reinterpret_cast<int*>(registers), static_cast<int>(functionId), static_cast<int>(subFunctionId)); __cpuidex(reinterpret_cast<int*>(registers), static_cast<int>(functionId), static_cast<int>(subFunctionId));
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c // https://en.wikipedia.org/wiki/CPUID
asm volatile ("cpuid" // Besoin d'être volatile ? asm volatile(
: "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output #ifdef NAZARA_PLATFORM_x64
: "a" (functionId), "c" (subFunctionId)); // input "pushq %%rbx \n\t" // save %rbx
#else
"pushl %%ebx \n\t" // save %ebx
#endif
"cpuid \n\t"
"movl %%ebx ,%[ebx] \n\t" // write the result into output var
#ifdef NAZARA_PLATFORM_x64
"popq %%rbx \n\t"
#else
"popl %%ebx \n\t"
#endif
: "=a"(registers[0]), [ebx] "=r"(registers[1]), "=c"(registers[2]), "=d"(registers[3]) // output
: "a"(functionId), "c" (subFunctionId)); // input
#else #else
NazaraInternalError("Cpuid has been called although it is not supported"); NazaraInternalError("Cpuid has been called although it is not supported");
#endif #endif
@ -33,7 +45,7 @@ namespace Nz
unsigned int HardwareInfoImpl::GetProcessorCount() unsigned int HardwareInfoImpl::GetProcessorCount()
{ {
// Plus simple (et plus portable) que de passer par le CPUID // Simpler (and more portable) than using CPUID
SYSTEM_INFO infos; SYSTEM_INFO infos;
GetNativeSystemInfo(&infos); GetNativeSystemInfo(&infos);
@ -52,7 +64,7 @@ namespace Nz
bool HardwareInfoImpl::IsCpuidSupported() bool HardwareInfoImpl::IsCpuidSupported()
{ {
#ifdef NAZARA_PLATFORM_x64 #ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits return true; // cpuid is always supported on x64 arch
#else #else
#if defined(NAZARA_COMPILER_MSVC) #if defined(NAZARA_COMPILER_MSVC)
int supported; int supported;

View File

@ -291,6 +291,7 @@ namespace Nz
declaration->EnableComponent(ParticleComponent_Normal, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, normal)); declaration->EnableComponent(ParticleComponent_Normal, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, normal));
declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, position)); declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, position));
declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Billboard, rotation)); declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Billboard, rotation));
declaration->EnableComponent(ParticleComponent_Size, ComponentType_Float2, NazaraOffsetOf(ParticleStruct_Billboard, size));
declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, velocity)); declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, velocity));
NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Billboard), "Invalid stride for declaration ParticleLayout_Billboard"); NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Billboard), "Invalid stride for declaration ParticleLayout_Billboard");

View File

@ -68,7 +68,12 @@ namespace Nz
std::size_t x = tileIndex % m_mapSize.x; std::size_t x = tileIndex % m_mapSize.x;
std::size_t y = tileIndex / m_mapSize.x; std::size_t y = tileIndex / m_mapSize.x;
Vector3f tileLeftCorner(x * m_tileSize.x, y * -m_tileSize.y, 0.f);
Vector3f tileLeftCorner;
if (m_isometricModeEnabled)
tileLeftCorner.Set(x * m_tileSize.x + m_tileSize.x/2.f * (y % 2), y/2.f * -m_tileSize.y, 0.f);
else
tileLeftCorner.Set(x * m_tileSize.x, y * -m_tileSize.y, 0.f);
*colorPtr++ = tile.color; *colorPtr++ = tile.color;
*posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner); *posPtr++ = instanceData->transformMatrix.Transform(tileLeftCorner);

View File

@ -0,0 +1,112 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Linux/SocketPollerImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Network/Posix/SocketImpl.hpp>
#include <cstring>
#include <unistd.h>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
SocketPollerImpl::SocketPollerImpl()
{
m_handle = epoll_create1(0);
}
SocketPollerImpl::~SocketPollerImpl()
{
close(m_handle);
}
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
{
return m_sockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
epoll_event event;
event.events = EPOLLIN;
event.data.fd = socket;
if (epoll_ctl(m_handle, EPOLL_CTL_ADD, socket, &event) != 0)
{
NazaraError("Failed to add socket to epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
return false;
}
m_sockets.insert(socket);
return true;
}
void SocketPollerImpl::UnregisterSocket(SocketHandle socket)
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
m_activeSockets.erase(socket);
m_sockets.erase(socket);
if (epoll_ctl(m_handle, EPOLL_CTL_DEL, socket, nullptr) != 0)
NazaraWarning("An error occured while removing socket from epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
{
int activeSockets;
// Reset status of sockets
m_events.resize(m_sockets.size());
std::memset(m_events.data(), 0, m_events.size() * sizeof(epoll_event));
activeSockets = epoll_wait(m_handle, m_events.data(), static_cast<int>(m_events.size()), static_cast<int>(msTimeout));
if (activeSockets == -1)
{
if (error)
*error = SocketImpl::TranslateErrnoToResolveError(errno);
return 0;
}
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketCount = activeSockets;
for (int i = 0; i < socketCount; ++i)
{
if (m_events[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
{
m_activeSockets.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) + ')');
activeSockets--;
}
}
}
if (error)
*error = SocketError_NoError;
return activeSockets;
}
}

View File

@ -0,0 +1,42 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLERIMPL_HPP
#define NAZARA_SOCKETPOLLERIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <unordered_set>
#include <vector>
#include <sys/epoll.h>
namespace Nz
{
class SocketPollerImpl
{
public:
SocketPollerImpl();
~SocketPollerImpl();
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_set<SocketHandle> m_sockets;
std::vector<epoll_event> m_events;
int m_handle;
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@ -2,6 +2,11 @@
// This file is part of the "Nazara Engine - Network module" // This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_IPADDRESSIMPL_HPP
#define NAZARA_IPADDRESSIMPL_HPP
#include <Nazara/Network/IpAddress.hpp> #include <Nazara/Network/IpAddress.hpp>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -30,3 +35,5 @@ namespace Nz
static ResolveError TranslateEAIErrorToResolveError(int error); static ResolveError TranslateEAIErrorToResolveError(int error);
}; };
} }
#endif // NAZARA_IPADDRESSIMPL_HPP

View File

@ -9,6 +9,7 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <poll.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
#include <Nazara/Network/Debug.hpp> #include <Nazara/Network/Debug.hpp>
@ -397,6 +398,23 @@ namespace Nz
return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data())); return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
} }
int SocketImpl::Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error)
{
NazaraAssert(fdarray && nfds > 0, "Invalid fdarray");
static_assert(sizeof(PollSocket) == sizeof(pollfd), "PollSocket size must match WSAPOLLFD size");
int result = poll(reinterpret_cast<pollfd*>(fdarray), static_cast<nfds_t>(nfds), timeout);
if (result < 0)
{
if (error)
*error = TranslateErrnoToResolveError(GetLastErrorCode());
return 0;
}
return result;
}
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error) bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
{ {

View File

@ -2,12 +2,26 @@
// This file is part of the "Nazara Engine - Network module" // This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETIMPL_HPP
#define NAZARA_SOCKETIMPL_HPP
#include <Nazara/Network/SocketHandle.hpp> #include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Enums.hpp> #include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp> #include <Nazara/Network/IpAddress.hpp>
#define NAZARA_NETWORK_POLL_SUPPORT 1
namespace Nz namespace Nz
{ {
struct PollSocket
{
SocketHandle fd;
short events;
short revents;
};
class SocketImpl class SocketImpl
{ {
public: public:
@ -42,6 +56,8 @@ namespace Nz
static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr);
static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr);
static int Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error);
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error); static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error); static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
@ -66,3 +82,5 @@ namespace Nz
static socketID s_socket; static socketID s_socket;
}; };
} }
#endif // NAZARA_SOCKETIMPL_HPP

View File

@ -0,0 +1,93 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Posix/SocketPollerImpl.hpp>
#include <poll.h>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_allSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
{
return m_allSockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
PollSocket entry = {
socket,
POLLRDNORM,
0
};
m_allSockets[socket] = m_sockets.size();
m_sockets.emplace_back(entry);
return true;
}
void SocketPollerImpl::UnregisterSocket(SocketHandle socket)
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
if (m_sockets.size() > 1U)
{
// Instead of using vector::erase, let's move the last element to the now unoccupied position
std::size_t entry = m_allSockets[socket];
// Get the last element and update it's position
const PollSocket& lastElement = m_sockets.back();
m_allSockets[lastElement.fd] = entry;
// 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);
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
{
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<int>(msTimeout), error);
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
{
m_activeSockets.insert(entry.fd);
if (--socketRemaining == 0)
break;
}
}
}
return activeSockets;
}
}

View File

@ -0,0 +1,42 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLERIMPL_HPP
#define NAZARA_SOCKETPOLLERIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Posix/SocketImpl.hpp>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace Nz
{
class SocketPollerImpl
{
public:
SocketPollerImpl() = default;
~SocketPollerImpl() = default;
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@ -0,0 +1,170 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/SocketPoller.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Network/Win32/SocketPollerImpl.hpp>
#elif defined(NAZARA_PLATFORM_LINUX)
#include <Nazara/Network/Linux/SocketPollerImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Network/Posix/SocketPollerImpl.hpp>
#else
#error Missing implementation: SocketPoller
#endif
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
/*!
* \ingroup network
* \class Nz::SocketPoller
* \brief Network class allowing an application to wait on multiples sockets for them to become active (readable)
*/
/*!
* \brief Constructs an empty SocketPoller object
*/
SocketPoller::SocketPoller() :
m_impl(new SocketPollerImpl)
{
}
/*!
* \brief Destructs the SocketPoller
*
* \remark When the SocketPoller gets destroyed, all sockets are automatically unregistered from it.
*/
SocketPoller::~SocketPoller()
{
delete m_impl;
}
/*!
* \brief Clears the SocketPoller
*
* This function reverts the SocketPoller to the initial state, unregistering every socket from the SocketPoller.
*
* \see Unregister
*/
void SocketPoller::Clear()
{
m_impl->Clear();
}
/*!
* \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.
*
* A socket in the ready 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.
*
* \param socket Reference to the socket to check
*
* \return True if the socket is available for reading without blocking, false otherwise
*
* \see Wait
*/
bool SocketPoller::IsReady(const AbstractSocket& socket) const
{
NazaraAssert(IsRegistered(socket), "Socket is not registered in the poller");
return m_impl->IsReady(socket.GetNativeHandle());
}
/*!
* \brief Checks if a specific socket is registered in the SocketPoller
*
* A registered socket is part of the SocketPoller and will be checked by the next Wait operations.
*
* \param socket Reference to the socket to check
*
* \return True if the socket is registered, false otherwise
*
* \see RegisterSocket
* \see UnregisterSocket
*/
bool SocketPoller::IsRegistered(const AbstractSocket& socket) const
{
return m_impl->IsRegistered(socket.GetNativeHandle());
}
/*!
* \brief Register a socket in the SocketPoller
*
* A registered socket is part of the SocketPoller and will be checked by the next Wait operations.
*
* The SocketPoller keeps a reference to the internal handle of registered socket, which should not be freed while it is registered in the SocketPooler.
*
* It is possible for this function to fail if too many sockets are registered in the SocketPoller, the maximum number of socket handled limit is OS-dependent.
*
* \remark It is an error to register a socket twice in the same SocketPoller.
* \remark The socket should not be freed while it is registered in the SocketPooler.
*
* \param socket Reference to the socket to register
*
* \return True if the socket is registered, false otherwise
*
* \see IsRegistered
* \see UnregisterSocket
*/
bool SocketPoller::RegisterSocket(AbstractSocket& socket)
{
NazaraAssert(!IsRegistered(socket), "This socket is already registered in this SocketPoller");
return m_impl->RegisterSocket(socket.GetNativeHandle());
}
/*!
* \brief Unregister a socket from the SocketPoller
*
* After calling UnregisterSocket, the socket is no longer part of the SocketPoller and thus, not taken into account by any further Wait call until registered again.
*
* This function must be called before destroying a socket part of the SocketPoller.
*
* \remark It is an error to try to unregister a non-registered socket from a SocketPoller.
*
* \param socket Reference to the socket to unregister
*
* \see IsRegistered
* \see RegisterSocket
*/
void SocketPoller::UnregisterSocket(AbstractSocket& socket)
{
NazaraAssert(IsRegistered(socket), "This socket is not registered in this SocketPoller");
return m_impl->UnregisterSocket(socket.GetNativeHandle());
}
/*!
* \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.
*
* \param msTimeout Maximum time to wait in milliseconds, 0 for infinity
*
* \remark It is an error to try to unregister a non-registered socket from a SocketPoller.
*
* \see IsReady
* \see RegisterSocket
*/
bool SocketPoller::Wait(UInt64 msTimeout)
{
SocketError error;
int readySockets = m_impl->Wait(msTimeout, &error);
if (error != SocketError_NoError)
{
NazaraError("SocketPoller encountered an error (code: 0x" + String::Number(error, 16) + ')');
return false;
}
return readySockets > 0;
}
}

View File

@ -262,6 +262,17 @@ namespace Nz
if (m_pendingPacket.headerReceived) if (m_pendingPacket.headerReceived)
{ {
UInt16 packetSize = static_cast<UInt16>(m_pendingPacket.data.GetSize()); //< Total packet size UInt16 packetSize = static_cast<UInt16>(m_pendingPacket.data.GetSize()); //< Total packet size
if (packetSize == 0)
{
// Special case: our packet carry no data
packet->Reset(m_pendingPacket.netcode);
// And reset every state
m_pendingPacket.data.Clear();
m_pendingPacket.headerReceived = false;
m_pendingPacket.received = 0;
return true;
}
std::size_t received; std::size_t received;
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received)) if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received))

View File

@ -13,12 +13,12 @@ namespace Nz
{ {
namespace Detail namespace Detail
{ {
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
using addrinfoImpl = addrinfoW; using addrinfoImpl = addrinfoW;
int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results) int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results)
{ {
return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), &hints, &servinfo); return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), hints, results);
} }
int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags) int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags)
@ -26,14 +26,14 @@ namespace Nz
std::array<wchar_t, NI_MAXHOST> hostnameBuffer; std::array<wchar_t, NI_MAXHOST> hostnameBuffer;
std::array<wchar_t, NI_MAXSERV> serviceBuffer; std::array<wchar_t, NI_MAXSERV> serviceBuffer;
int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), static_cast<DWORD>(hostnameBuffer.size()), serviceBuffer.data(), static_cast<DWORD>(serviceBuffer.size()), flags);
if (result == 0) if (result == 0)
{ {
if (hostname) if (hostname)
hostname->Set(hostnameBuffer.data()); *hostname = std::move(String::Unicode(hostnameBuffer.data()));
if (service) if (service)
service->Set(serviceBuffer.data()); *service = std::move(String::Unicode(serviceBuffer.data()));
} }
return result; return result;
@ -105,7 +105,7 @@ namespace Nz
return IpAddress::Invalid; return IpAddress::Invalid;
} }
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info) IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info)
{ {
switch (info->ai_family) switch (info->ai_family)

View File

@ -2,6 +2,11 @@
// This file is part of the "Nazara Engine - Network module" // This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_IPADDRESSIMPL_HPP
#define NAZARA_IPADDRESSIMPL_HPP
#include <Nazara/Network/IpAddress.hpp> #include <Nazara/Network/IpAddress.hpp>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
@ -17,7 +22,7 @@ namespace Nz
~IpAddressImpl() = delete; ~IpAddressImpl() = delete;
static IpAddress FromAddrinfo(const addrinfo* info); static IpAddress FromAddrinfo(const addrinfo* info);
#if NAZARA_CORE_WINDOWS_VISTA #if NAZARA_CORE_WINDOWS_NT6
static IpAddress FromAddrinfo(const addrinfoW* info); static IpAddress FromAddrinfo(const addrinfoW* info);
#endif #endif
static IpAddress FromSockAddr(const sockaddr* address); static IpAddress FromSockAddr(const sockaddr* address);
@ -33,3 +38,5 @@ namespace Nz
static ResolveError TranslateWSAErrorToResolveError(int error); static ResolveError TranslateWSAErrorToResolveError(int error);
}; };
} }
#endif // NAZARA_IPADDRESSIMPL_HPP

View File

@ -7,18 +7,21 @@
#include <Nazara/Core/Log.hpp> #include <Nazara/Core/Log.hpp>
#include <Nazara/Network/Win32/IpAddressImpl.hpp> #include <Nazara/Network/Win32/IpAddressImpl.hpp>
#include <Winsock2.h> #if defined(NAZARA_COMPILER_MINGW) && __GNUC__ < 5
// Some compilers (olders versions of MinGW) are lacking Mstcpip.h which defines the following struct/#define // Some compilers (olders versions of MinGW) are lacking Mstcpip.h which defines the following struct/#define
// Define them ourself for now
struct tcp_keepalive struct tcp_keepalive
{ {
u_long onoff; u_long onoff;
u_long keepalivetime; u_long keepalivetime;
u_long keepaliveinterval; u_long keepaliveinterval;
}; };
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
#else
#include <Mstcpip.h>
#endif
#include <Winsock2.h>
#include <Nazara/Network/Debug.hpp> #include <Nazara/Network/Debug.hpp>
@ -412,6 +415,34 @@ namespace Nz
return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data())); return IpAddressImpl::FromSockAddr(reinterpret_cast<sockaddr*>(nameBuffer.data()));
} }
int SocketImpl::Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error)
{
NazaraAssert(fdarray && nfds > 0, "Invalid fdarray");
#if NAZARA_NETWORK_POLL_SUPPORT
static_assert(sizeof(PollSocket) == sizeof(WSAPOLLFD), "PollSocket size must match WSAPOLLFD size");
int result = WSAPoll(reinterpret_cast<WSAPOLLFD*>(fdarray), static_cast<ULONG>(nfds), timeout);
if (result == SOCKET_ERROR)
{
int errorCode = WSAGetLastError();
if (error)
*error = TranslateWSAErrorToSocketError(errorCode);
return 0;
}
if (error)
*error = SocketError_NoError;
return result;
#else
if (error)
*error = SocketError_NotSupported;
return 0;
#endif
}
bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error) bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error)
{ {

View File

@ -2,13 +2,27 @@
// This file is part of the "Nazara Engine - Network module" // This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETIMPL_HPP
#define NAZARA_SOCKETIMPL_HPP
#include <Nazara/Network/SocketHandle.hpp> #include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Enums.hpp> #include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp> #include <Nazara/Network/IpAddress.hpp>
#include <winsock2.h> #include <winsock2.h>
#define NAZARA_NETWORK_POLL_SUPPORT NAZARA_CORE_WINDOWS_NT6
namespace Nz namespace Nz
{ {
struct PollSocket
{
SocketHandle fd;
short events;
short revents;
};
class SocketImpl class SocketImpl
{ {
public: public:
@ -43,6 +57,8 @@ namespace Nz
static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr);
static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr);
static int Poll(PollSocket* fdarray, std::size_t nfds, int timeout, SocketError* error);
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error); static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error); static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
@ -66,3 +82,5 @@ namespace Nz
static WSADATA s_WSA; static WSADATA s_WSA;
}; };
} }
#endif // NAZARA_SOCKETIMPL_HPP

View File

@ -0,0 +1,149 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Win32/SocketPollerImpl.hpp>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
SocketPollerImpl::SocketPollerImpl()
{
#if !NAZARA_NETWORK_POLL_SUPPORT
FD_ZERO(&m_activeSockets);
FD_ZERO(&m_sockets);
#endif
}
void SocketPollerImpl::Clear()
{
#if NAZARA_NETWORK_POLL_SUPPORT
m_activeSockets.clear();
m_allSockets.clear();
m_sockets.clear();
#else
FD_ZERO(&m_activeSockets);
FD_ZERO(&m_sockets);
#endif
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
{
#if NAZARA_NETWORK_POLL_SUPPORT
return m_activeSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_activeSockets) != 0;
#endif
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
{
#if NAZARA_NETWORK_POLL_SUPPORT
return m_allSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_sockets) != 0;
#endif
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
#if NAZARA_NETWORK_POLL_SUPPORT
PollSocket entry = {
socket,
POLLRDNORM,
0
};
m_allSockets[socket] = m_sockets.size();
m_sockets.emplace_back(entry);
#else
if (m_sockets.fd_count > FD_SETSIZE)
{
NazaraError("Socket count exceeding FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")");
return false;
}
FD_SET(socket, &m_sockets);
#endif
return true;
}
void SocketPollerImpl::UnregisterSocket(SocketHandle socket)
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
#if NAZARA_NETWORK_POLL_SUPPORT
if (m_sockets.size() > 1U)
{
// Instead of using vector::erase, let's move the last element to the now unoccupied position
std::size_t entry = m_allSockets[socket];
// Get the last element and update it's position
const PollSocket& lastElement = m_sockets.back();
m_allSockets[lastElement.fd] = entry;
// 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);
#else
FD_CLR(socket, &m_activeSockets);
FD_CLR(socket, &m_sockets);
#endif
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
{
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<int>(msTimeout), error);
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
{
m_activeSockets.insert(entry.fd);
if (--socketRemaining == 0)
break;
}
}
}
#else
m_activeSockets = m_sockets;
timeval tv;
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
activeSockets = ::select(0xDEADBEEF, &m_activeSockets, nullptr, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
if (activeSockets == SOCKET_ERROR)
{
if (error)
*error = SocketImpl::TranslateWSAErrorToSocketError(WSAGetLastError());
return 0;
}
if (error)
*error = SocketError_NoError;
#endif
return activeSockets;
}
}

View File

@ -0,0 +1,48 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SOCKETPOLLERIMPL_HPP
#define NAZARA_SOCKETPOLLERIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Win32/SocketImpl.hpp>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <winsock2.h>
namespace Nz
{
class SocketPollerImpl
{
public:
SocketPollerImpl();
~SocketPollerImpl() = default;
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
#if NAZARA_NETWORK_POLL_SUPPORT
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
#else
fd_set m_sockets;
fd_set m_activeSockets;
#endif
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@ -37,6 +37,10 @@ namespace Nz
if (parameters.custom.GetBooleanParameter("SkipNativeOBJLoader", &skip) && skip) if (parameters.custom.GetBooleanParameter("SkipNativeOBJLoader", &skip) && skip)
return Ternary_False; return Ternary_False;
OBJParser parser;
if (!parser.Check(stream))
return Ternary_False;
return Ternary_Unknown; return Ternary_Unknown;
} }

View File

@ -13,9 +13,87 @@
namespace Nz namespace Nz
{ {
bool OBJParser::Check(Stream& stream)
{
m_currentStream = &stream;
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
// Force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode;
if ((stream.GetStreamOptions() & StreamOption_Text) == 0)
{
stream.EnableTextMode(true);
resetTextMode.Reset([&stream] ()
{
stream.EnableTextMode(false);
});
}
unsigned int failureCount = 0;
while (Advance(false))
{
switch (std::tolower(m_currentLine[0]))
{
case '#': //< Comment
failureCount--;
break;
case 'f': //< Face
case 'g': //< Group (inside a mesh)
case 'o': //< Object (defines a mesh)
case 's': //< Smooth
{
if (m_currentLine.GetSize() > 1 && m_currentLine[1] == ' ')
return true;
break;
}
case 'm': //< MTLLib
if (m_currentLine.GetWord(0).ToLower() == "mtllib")
return true;
break;
case 'u': //< Usemtl
if (m_currentLine.GetWord(0).ToLower() == "usemtl")
return true;
break;
case 'v': //< Position/Normal/Texcoords
{
String word = m_currentLine.GetWord(0).ToLower();
if (word == 'v')
return true;
else if (word == "vn")
return true;
else if (word == "vt")
return true;
break;
}
default:
break;
}
if (++failureCount > 20U)
return false;
}
return false;
}
bool OBJParser::Parse(Nz::Stream& stream, UInt32 reservedVertexCount) bool OBJParser::Parse(Nz::Stream& stream, UInt32 reservedVertexCount)
{ {
m_currentStream = &stream; m_currentStream = &stream;
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
// Force stream in text mode, reset it at the end // Force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode; Nz::CallOnExit resetTextMode;
@ -31,9 +109,6 @@ namespace Nz
String matName, meshName; String matName, meshName;
matName = meshName = "default"; matName = meshName = "default";
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
m_meshes.clear(); m_meshes.clear();
m_mtlLib.Clear(); m_mtlLib.Clear();

View File

@ -1284,6 +1284,9 @@ namespace Nz
bool PixelFormat::Initialize() bool PixelFormat::Initialize()
{ {
Bitset<> b32(0xFFFFFFFF);
b32.Resize(128);
// Setup informations about every pixel format // Setup informations about every pixel format
s_pixelFormatInfos[PixelFormatType_A8] = PixelFormatInfo("A8", PixelFormatContent_ColorRGBA, 0, 0, 0, 0xFF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_A8] = PixelFormatInfo("A8", PixelFormatContent_ColorRGBA, 0, 0, 0, 0xFF, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_BGR8] = PixelFormatInfo("BGR8", PixelFormatContent_ColorRGBA, 0x0000FF, 0x00FF00, 0xFF0000, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_BGR8] = PixelFormatInfo("BGR8", PixelFormatContent_ColorRGBA, 0x0000FF, 0x00FF00, 0xFF0000, 0, PixelFormatSubType_Unsigned);
@ -1317,18 +1320,18 @@ namespace Nz
s_pixelFormatInfos[PixelFormatType_RGB16F] = PixelFormatInfo("RGB16F", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Half); s_pixelFormatInfos[PixelFormatType_RGB16F] = PixelFormatInfo("RGB16F", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Half);
s_pixelFormatInfos[PixelFormatType_RGB16I] = PixelFormatInfo("RGB16I", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormatType_RGB16I] = PixelFormatInfo("RGB16I", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGB16UI] = PixelFormatInfo("RGB16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGB16UI] = PixelFormatInfo("RGB16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGB32F] = PixelFormatInfo("RGB32F", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Half); s_pixelFormatInfos[PixelFormatType_RGB32F] = PixelFormatInfo("RGB32F", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Float);
s_pixelFormatInfos[PixelFormatType_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormatType_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGB32UI] = PixelFormatInfo("RGB32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGB32UI] = PixelFormatInfo("RGB32UI", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA4] = PixelFormatInfo("RGBA4", PixelFormatContent_ColorRGBA, 0xF000, 0x0F00, 0x00F0, 0x000F, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGBA4] = PixelFormatInfo("RGBA4", PixelFormatContent_ColorRGBA, 0xF000, 0x0F00, 0x00F0, 0x000F, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGB5A1] = PixelFormatInfo("RGB5A1", PixelFormatContent_ColorRGBA, 0xF800, 0x07C0, 0x003E, 0x0001, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGB5A1] = PixelFormatInfo("RGB5A1", PixelFormatContent_ColorRGBA, 0xF800, 0x07C0, 0x003E, 0x0001, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA8] = PixelFormatInfo("RGBA8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGBA8] = PixelFormatInfo("RGBA8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA16F] = PixelFormatInfo("RGBA16F", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Half); s_pixelFormatInfos[PixelFormatType_RGBA16F] = PixelFormatInfo("RGBA16F", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Half);
s_pixelFormatInfos[PixelFormatType_RGBA16I] = PixelFormatInfo("RGBA16I", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormatType_RGBA16I] = PixelFormatInfo("RGBA16I", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGBA16UI] = PixelFormatInfo("RGBA16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGBA16UI] = PixelFormatInfo("RGBA16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGBA32F] = PixelFormatInfo("RGBA32F", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Half); s_pixelFormatInfos[PixelFormatType_RGBA32F] = PixelFormatInfo("RGBA32F", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Float);
s_pixelFormatInfos[PixelFormatType_RGBA32I] = PixelFormatInfo("RGBA32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormatType_RGBA32I] = PixelFormatInfo("RGBA32I", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGBA32UI] = PixelFormatInfo("RGBA32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_RGBA32UI] = PixelFormatInfo("RGBA32UI", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_Depth16] = PixelFormatInfo("Depth16", PixelFormatContent_DepthStencil, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_Depth16] = PixelFormatInfo("Depth16", PixelFormatContent_DepthStencil, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_Depth24] = PixelFormatInfo("Depth24", PixelFormatContent_DepthStencil, 0xFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_Depth24] = PixelFormatInfo("Depth24", PixelFormatContent_DepthStencil, 0xFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_Depth24Stencil8] = PixelFormatInfo("Depth24Stencil8", PixelFormatContent_DepthStencil, 0xFFFFFF00, 0x000000FF, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormatType_Depth24Stencil8] = PixelFormatInfo("Depth24Stencil8", PixelFormatContent_DepthStencil, 0xFFFFFF00, 0x000000FF, 0, 0, PixelFormatSubType_Unsigned);

View File

@ -102,10 +102,14 @@ namespace Nz
return false; return false;
} }
if (!Window::Initialize()) bool bParam;
if (!s_initializationParameters.GetBooleanParameter("NoWindowSystem", &bParam) || !bParam)
{ {
NazaraError("Failed to initialize window's system"); if (!Window::Initialize())
return false; {
NazaraError("Failed to initialize window's system");
return false;
}
} }
// On enregistre les loaders pour les extensions // On enregistre les loaders pour les extensions
@ -147,6 +151,11 @@ namespace Nz
return s_moduleReferenceCounter != 0; return s_moduleReferenceCounter != 0;
} }
void Utility::SetParameters(const ParameterList& parameters)
{
s_initializationParameters = parameters;
}
void Utility::Uninitialize() void Utility::Uninitialize()
{ {
if (s_moduleReferenceCounter != 1) if (s_moduleReferenceCounter != 1)
@ -227,5 +236,6 @@ namespace Nz
static_assert(ComponentType_Max+1 == 14, "Component stride array is incomplete"); static_assert(ComponentType_Max+1 == 14, "Component stride array is incomplete");
ParameterList Utility::s_initializationParameters;
unsigned int Utility::s_moduleReferenceCounter = 0; unsigned int Utility::s_moduleReferenceCounter = 0;
} }

View File

@ -29,6 +29,11 @@ namespace Nz
Window* fullscreenWindow = nullptr; Window* fullscreenWindow = nullptr;
} }
Window::~Window()
{
Destroy();
}
bool Window::Create(VideoMode mode, const String& title, UInt32 style) bool Window::Create(VideoMode mode, const String& title, UInt32 style)
{ {
// Si la fenêtre est déjà ouverte, nous conservons sa position // Si la fenêtre est déjà ouverte, nous conservons sa position

View File

@ -9,7 +9,17 @@
#include <Nazara/Utility/PixelFormat.hpp> #include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Utility/X11/Display.hpp> #include <Nazara/Utility/X11/Display.hpp>
#include <xcb/xcb_image.h> #include <xcb/xcb_image.h>
#include <xcb/xcb_renderutil.h>
// Some older versions of xcb/util-renderutil (notably the one available on Travis CI) use `template` as an argument name
// This is a fixed bug (https://cgit.freedesktop.org/xcb/util-renderutil/commit/?id=8d15acc45a47dc4c922eee5b99885db42bc62c17) but until Travis-CI
// has upgraded their Ubuntu version, I'm forced to use this ugly trick.
#define template ptemplate
extern "C"
{
#include <xcb/xcb_renderutil.h>
}
#undef template
#include <Nazara/Utility/Debug.hpp> #include <Nazara/Utility/Debug.hpp>
namespace Nz namespace Nz

View File

@ -15,12 +15,12 @@ SCENARIO("Model", "[GRAPHICS][MODEL]")
Nz::ModelRef model = Nz::Model::New(); Nz::ModelRef model = Nz::Model::New();
REQUIRE(model->LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj", params)); REQUIRE(model->LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj", params));
REQUIRE(model->GetMaterialCount() == 2); REQUIRE(model->GetMaterialCount() == 1);
REQUIRE(model->GetSkin() == 0); REQUIRE(model->GetSkin() == 0);
REQUIRE(model->GetSkinCount() == 1); REQUIRE(model->GetSkinCount() == 1);
Nz::Material* material = model->GetMaterial(0); Nz::Material* material = model->GetMaterial(0);
REQUIRE(material->GetAmbientColor() == Nz::Color(128)); REQUIRE(material->GetAmbientColor() == Nz::Color::Black);
} }
} }
} }

View File

@ -40,7 +40,7 @@ SCENARIO("IpAddress", "[NETWORK][IPADDRESS]")
Nz::IpAddress google(8, 8, 8, 8); Nz::IpAddress google(8, 8, 8, 8);
THEN("Google (DNS) is 8.8.8.8") THEN("Google (DNS) is 8.8.8.8")
{ {
REQUIRE(Nz::IpAddress::ResolveAddress(google) == "google-public-dns-a.google.com"); REQUIRE(Nz::IpAddress::ResolveAddress(google) == "google-public-dns-a.google.com");
} }
} }
} }

View File

@ -7,13 +7,18 @@ SCENARIO("RUdpConnection", "[NETWORK][RUDPCONNECTION]")
{ {
GIVEN("Two RUdpConnection, one client, one server") GIVEN("Two RUdpConnection, one client, one server")
{ {
Nz::UInt16 port = 64266; // Disabled for now
/*Nz::UInt16 port = 64266;
Nz::RUdpConnection server; Nz::RUdpConnection server;
REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port)); REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port));
Nz::IpAddress serverIP = server.GetBoundAddress();
Nz::IpAddress serverIP(Nz::IpAddress::LoopbackIpV4.ToIPv4(), port);
REQUIRE(serverIP.IsValid()); REQUIRE(serverIP.IsValid());
Nz::RUdpConnection client; Nz::RUdpConnection client;
REQUIRE(client.Listen(Nz::NetProtocol_IPv4, port + 1)); REQUIRE(client.Listen(Nz::NetProtocol_IPv4, port + 1));
Nz::IpAddress clientIP = client.GetBoundAddress(); Nz::IpAddress clientIP = client.GetBoundAddress();
REQUIRE(client.Connect(serverIP)); REQUIRE(client.Connect(serverIP));
REQUIRE(clientIP.IsValid()); REQUIRE(clientIP.IsValid());
@ -30,11 +35,13 @@ SCENARIO("RUdpConnection", "[NETWORK][RUDPCONNECTION]")
{ {
Nz::RUdpMessage rudpMessage; Nz::RUdpMessage rudpMessage;
server.Update(); server.Update();
REQUIRE(server.PollMessage(&rudpMessage)); REQUIRE(server.PollMessage(&rudpMessage));
Nz::Vector3f result; Nz::Vector3f result;
rudpMessage.data >> result; rudpMessage.data >> result;
REQUIRE(result == vector123); REQUIRE(result == vector123);
} }
} }*/
} }
} }

View File

@ -0,0 +1,84 @@
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/SocketPoller.hpp>
#include <Nazara/Network/TcpClient.hpp>
#include <Nazara/Network/TcpServer.hpp>
#include <Catch/catch.hpp>
#include <random>
SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]")
{
GIVEN("A TcpServer and a TcpClient in a selector")
{
std::random_device rd;
std::uniform_int_distribution<Nz::UInt16> dis(1025, 65535);
Nz::UInt16 port = dis(rd);
Nz::TcpServer server;
server.EnableBlocking(false);
REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port) == Nz::SocketState_Bound);
Nz::IpAddress serverIP(Nz::IpAddress::LoopbackIpV4.ToIPv4(), port);
REQUIRE(serverIP.IsValid());
Nz::SocketPoller serverPoller;
Nz::TcpClient clientToServer;
WHEN("We register the server socket to the poller")
{
REQUIRE(serverPoller.RegisterSocket(server));
THEN("The poller should have registered our socket")
{
REQUIRE(serverPoller.IsRegistered(server));
}
AND_THEN("We connect using a TcpClient")
{
Nz::SocketState state = clientToServer.Connect(serverIP);
REQUIRE(state != Nz::SocketState_NotConnected);
AND_THEN("We wait on our selector, it should return true")
{
REQUIRE(serverPoller.Wait(1000));
Nz::TcpClient serverToClient;
REQUIRE(server.AcceptClient(&serverToClient));
WHEN("We register the client socket to the poller")
{
REQUIRE(serverPoller.RegisterSocket(serverToClient));
THEN("The poller should have registered our socket")
{
REQUIRE(serverPoller.IsRegistered(serverToClient));
}
AND_WHEN("We test sending data from the client to the server and checking the poller")
{
std::array<char, 5> buffer = {"Data"};
std::size_t sent;
REQUIRE(clientToServer.Send(buffer.data(), buffer.size(), &sent));
REQUIRE(sent == buffer.size());
REQUIRE(serverPoller.Wait(1000));
REQUIRE(serverPoller.IsReady(serverToClient));
REQUIRE(serverToClient.Read(buffer.data(), buffer.size()) == sent);
AND_THEN("Our selector should report no socket ready")
{
REQUIRE(!serverPoller.Wait(100));
REQUIRE(!serverPoller.IsReady(serverToClient));
}
}
}
}
}
}
}
}

View File

@ -1,33 +1,35 @@
#include <Nazara/Core/Thread.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/TcpClient.hpp> #include <Nazara/Network/TcpClient.hpp>
#include <Nazara/Network/TcpServer.hpp> #include <Nazara/Network/TcpServer.hpp>
#include <Catch/catch.hpp> #include <Catch/catch.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <random> #include <random>
SCENARIO("TCP", "[NETWORK][TCP]") SCENARIO("TCP", "[NETWORK][TCP]")
{ {
GIVEN("Two TCP, one client, one server") GIVEN("Two TCP, one client, one server")
{ {
// Avoid reusing the same socket
std::random_device rd; std::random_device rd;
std::mt19937 gen(rd()); std::uniform_int_distribution<Nz::UInt16> dis(1025, 65535);
std::uniform_int_distribution<> dis(1025, 64245);
Nz::UInt16 port = dis(gen); Nz::UInt16 port = dis(rd);
Nz::TcpServer server; Nz::TcpServer server;
server.EnableBlocking(false); server.EnableBlocking(false);
REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port) == Nz::SocketState_Bound); REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port) == Nz::SocketState_Bound);
Nz::IpAddress serverIP = server.GetBoundAddress();
Nz::IpAddress serverIP(Nz::IpAddress::LoopbackIpV4.ToIPv4(), port);
REQUIRE(serverIP.IsValid()); REQUIRE(serverIP.IsValid());
Nz::TcpClient client; Nz::TcpClient client;
REQUIRE(client.Connect(serverIP) == Nz::SocketState_Connecting); REQUIRE(client.Connect(serverIP) == Nz::SocketState_Connecting);
Nz::IpAddress clientIP = client.GetRemoteAddress(); Nz::IpAddress clientIP = client.GetRemoteAddress();
REQUIRE(clientIP.IsValid()); REQUIRE(clientIP.IsValid());
Nz::Thread::Sleep(100);
Nz::TcpClient serverToClient; Nz::TcpClient serverToClient;
REQUIRE(server.AcceptClient(&serverToClient)); REQUIRE(server.AcceptClient(&serverToClient));

View File

@ -1,20 +1,26 @@
#include <Nazara/Network/UdpSocket.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Math/Vector3.hpp> #include <Nazara/Math/Vector3.hpp>
#include <Nazara/Network/UdpSocket.hpp>
#include <Nazara/Network/NetPacket.hpp> #include <Nazara/Network/NetPacket.hpp>
#include <Catch/catch.hpp>
#include <random>
SCENARIO("UdpSocket", "[NETWORK][UDPSOCKET]") SCENARIO("UdpSocket", "[NETWORK][UDPSOCKET]")
{ {
GIVEN("Two UdpSocket, one client, one server") GIVEN("Two UdpSocket, one client, one server")
{ {
Nz::UInt16 port = 64256; std::random_device rd;
std::uniform_int_distribution<Nz::UInt16> dis(1025, 65535);
Nz::UInt16 port = dis(rd);
Nz::UdpSocket server(Nz::NetProtocol_IPv4); Nz::UdpSocket server(Nz::NetProtocol_IPv4);
REQUIRE(server.Bind(port) == Nz::SocketState_Bound); REQUIRE(server.Bind(port) == Nz::SocketState_Bound);
Nz::IpAddress serverIP = server.GetBoundAddress();
Nz::IpAddress serverIP(Nz::IpAddress::LoopbackIpV4.ToIPv4(), port);
REQUIRE(serverIP.IsValid()); REQUIRE(serverIP.IsValid());
Nz::UdpSocket client(Nz::NetProtocol_IPv4); Nz::UdpSocket client(Nz::NetProtocol_IPv4);
REQUIRE(client.Bind(port + 1) == Nz::SocketState_Bound); REQUIRE(client.Bind(port + 1) == Nz::SocketState_Bound);
Nz::IpAddress clientIP = client.GetBoundAddress(); Nz::IpAddress clientIP = client.GetBoundAddress();
REQUIRE(clientIP.IsValid()); REQUIRE(clientIP.IsValid());
@ -30,6 +36,7 @@ SCENARIO("UdpSocket", "[NETWORK][UDPSOCKET]")
Nz::NetPacket resultPacket; Nz::NetPacket resultPacket;
Nz::IpAddress fromIp; Nz::IpAddress fromIp;
REQUIRE(server.ReceivePacket(&resultPacket, &fromIp)); REQUIRE(server.ReceivePacket(&resultPacket, &fromIp));
Nz::Vector3f result; Nz::Vector3f result;
resultPacket >> result; resultPacket >> result;
REQUIRE(result == vector123); REQUIRE(result == vector123);

View File

@ -5,17 +5,20 @@ SCENARIO("Application", "[NDK][APPLICATION]")
{ {
GIVEN("An application") GIVEN("An application")
{ {
Ndk::Application application; Nz::Window& window = Ndk::Application::Instance()->AddWindow<Nz::Window>();
application.AddWorld();
Nz::Window& window = application.AddWindow<Nz::Window>();
WHEN("We close the open window") WHEN("We open a window")
{ {
window.Close(); REQUIRE(window.Create(Nz::VideoMode(800, 600, 32), "Nazara Unit Tests"));
THEN("Application should close") AND_WHEN("We close the open window")
{ {
REQUIRE(!application.Run()); window.Close();
THEN("Application should close")
{
REQUIRE(!Ndk::Application::Instance()->Run());
}
} }
} }
} }

View File

@ -6,6 +6,18 @@ namespace
class TestComponent : public Ndk::Component<TestComponent> class TestComponent : public Ndk::Component<TestComponent>
{ {
public: public:
TestComponent(int value) :
m_value(value)
{
}
int GetValue() const
{
return m_value;
}
int m_value;
static Ndk::ComponentIndex componentIndex; static Ndk::ComponentIndex componentIndex;
}; };
@ -16,7 +28,7 @@ SCENARIO("Component", "[NDK][COMPONENT]")
{ {
GIVEN("Our TestComponent") GIVEN("Our TestComponent")
{ {
TestComponent testComponent; TestComponent testComponent(42);
WHEN("We clone it") WHEN("We clone it")
{ {
@ -24,7 +36,7 @@ SCENARIO("Component", "[NDK][COMPONENT]")
THEN("We should get a copy") THEN("We should get a copy")
{ {
REQUIRE(dynamic_cast<TestComponent*>(clone.get()) != nullptr); REQUIRE(static_cast<TestComponent*>(clone.get())->GetValue() == 42);
} }
} }
} }

View File

@ -6,15 +6,23 @@ namespace
class TestSystem : public Ndk::System<TestSystem> class TestSystem : public Ndk::System<TestSystem>
{ {
public: public:
TestSystem() TestSystem(int value) :
m_value(value)
{ {
} }
int GetValue() const
{
return m_value;
}
~TestSystem() = default; ~TestSystem() = default;
static Ndk::SystemIndex systemIndex; static Ndk::SystemIndex systemIndex;
private: private:
int m_value;
void OnUpdate(float elapsedTime) override void OnUpdate(float elapsedTime) override
{ {
} }
@ -27,7 +35,7 @@ SCENARIO("System", "[NDK][SYSTEM]")
{ {
GIVEN("Our TestSystem") GIVEN("Our TestSystem")
{ {
TestSystem testSystem; TestSystem testSystem(666);
WHEN("We clone it") WHEN("We clone it")
{ {
@ -35,7 +43,7 @@ SCENARIO("System", "[NDK][SYSTEM]")
THEN("We should get a copy") THEN("We should get a copy")
{ {
REQUIRE(dynamic_cast<TestSystem*>(clone.get()) != nullptr); REQUIRE(static_cast<TestSystem*>(clone.get())->GetValue() == 666);
} }
} }
} }

View File

@ -1,14 +1,16 @@
#define CATCH_CONFIG_RUNNER #define CATCH_CONFIG_RUNNER
#include <Catch/catch.hpp> #include <Catch/catch.hpp>
#include <Nazara/Audio/Audio.hpp> #include <NDK/Application.hpp>
#include <Nazara/Core/Core.hpp> #include <Nazara/Core/Log.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Network/Network.hpp> #include <Nazara/Network/Network.hpp>
int main(int argc, char* const argv[]) int main(int argc, char* argv[])
{ {
Nz::Initializer<Nz::Audio, Nz::Core, Nz::Graphics, Nz::Network> modules; Ndk::Application application(argc, argv);
Nz::Initializer<Nz::Network> modules;
Nz::Log::GetLogger()->EnableStdReplication(false);
int result = Catch::Session().run(argc, argv); int result = Catch::Session().run(argc, argv);