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

This commit is contained in:
Lynix 2016-10-12 16:51:18 +02:00
commit 561c0cf51f
95 changed files with 2139 additions and 348 deletions

11
.gitignore vendored
View File

@ -1,14 +1,23 @@
# Nazara build
build/config.lua
# Nazara libraries
lib/*
# Nazara package
package/*
# Example files
examples/bin/*.exe
examples/bin/*.pdb
examples/bin/*.dll
examples/bin/*.so
# Unit tests
tests/*.exe
tests/*.pdb
tests/*.dll
tests/*.so
lib/*
# Example generated files
examples/bin/HardwareInfo.txt

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 EnsureViewportUpdate() const;
inline float GetAspectRatio() const override;
inline Nz::Vector3f GetEyePosition() const override;
inline Nz::Vector3f GetForward() const override;
float GetAspectRatio() const override;
Nz::Vector3f GetEyePosition() const override;
Nz::Vector3f GetForward() const override;
inline float GetFOV() const;
inline const Nz::Frustumf& GetFrustum() const override;
const Nz::Frustumf& GetFrustum() const override;
inline unsigned int GetLayer() const;
inline const Nz::Matrix4f& GetProjectionMatrix() const override;
const Nz::Matrix4f& GetProjectionMatrix() const override;
inline Nz::ProjectionType GetProjectionType() 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::Matrix4f& GetViewMatrix() const override;
inline const Nz::Recti& GetViewport() const override;
inline float GetZFar() const override;
inline float GetZNear() const override;
const Nz::Matrix4f& GetViewMatrix() const override;
const Nz::Recti& GetViewport() const override;
float GetZFar() const override;
float GetZNear() const override;
inline void SetFOV(float fov);
inline void SetLayer(unsigned int layer);

View File

@ -97,40 +97,15 @@ namespace Ndk
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
* \return Field of view of the camera
*/
inline float CameraComponent::GetFOV() const
float CameraComponent::GetFOV() const
{
return m_fov;
}
/*!
* \brief Gets the frutum of the camera
* \return A constant reference to the frustum of the camera
*/
inline const Nz::Frustumf& CameraComponent::GetFrustum() const
{
EnsureFrustumUpdate();
return m_frustum;
}
/*!
* \brief Gets the layer of the camera
* \return Layer of the camera
@ -141,18 +116,6 @@ namespace Ndk
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
* \return Projection type of the camera
@ -173,16 +136,6 @@ namespace Ndk
return m_size;
}
/*!
* \brief Gets the target of the camera
* \return A constant reference to the render target of the camera
*/
inline const Nz::RenderTarget* CameraComponent::GetTarget() const
{
return m_target;
}
/*!
* \brief Gets the target region of the camera
* \return A constant reference to the target region of the camera
@ -193,50 +146,6 @@ namespace Ndk
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
*

View File

@ -172,4 +172,4 @@ namespace Ndk
InvalidateBoundingVolume();
InvalidateRenderables();
}
}
}

View File

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

View File

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

View File

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

View File

@ -35,6 +35,17 @@ namespace Ndk
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
*
@ -53,7 +64,6 @@ namespace Ndk
*
* \remark Produces a NazaraAssert if entity is invalid or has no NodeComponent
*/
Nz::Vector3f CameraComponent::GetForward() const
{
NazaraAssert(m_entity && m_entity->HasComponent<NodeComponent>(), "CameraComponent requires NodeComponent");
@ -61,6 +71,77 @@ namespace Ndk
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
*

View File

@ -167,8 +167,7 @@ namespace Ndk
*
* \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)
{
@ -204,6 +203,9 @@ namespace Ndk
}
break;
}
default:
break;
}
}

View File

@ -78,9 +78,10 @@ namespace Ndk
});
/*********************************** 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(argumentCount);
Nz::PlacementNew(instance, Nz::SoundBuffer::New());
return true;

View File

@ -13,7 +13,7 @@ namespace Ndk
void LuaBinding::BindCore()
{
/*********************************** 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;
Nz::Int64 startingValue = lua.Check<Nz::Int64>(&argIndex, 0);
@ -44,9 +44,9 @@ namespace Ndk
});
/********************************* 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;
switch (argCount)
@ -138,9 +138,9 @@ namespace Ndk
/*********************************** Nz::File ***********************************/
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;
switch (argCount)

View File

@ -20,8 +20,10 @@ namespace Ndk
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());
return true;
});

View File

@ -14,9 +14,10 @@ namespace Ndk
void LuaBinding::BindMath()
{
/*********************************** 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)
{
case 0:
@ -154,9 +155,10 @@ namespace Ndk
});
/*********************************** 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)
{
case 0:
@ -309,9 +311,10 @@ namespace Ndk
});
/*********************************** 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)
{
case 0:
@ -337,6 +340,9 @@ namespace Ndk
case 4:
Nz::PlacementNew(quaternion, lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3), lua.CheckNumber(4));
return true;
default:
break;
}
lua.Error("No matching overload for Quaternion constructor");
@ -411,9 +417,10 @@ namespace Ndk
});
/*********************************** 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)
{
case 0:
@ -533,9 +540,10 @@ namespace Ndk
});
/*********************************** 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)
{
case 0:
@ -546,7 +554,7 @@ namespace Ndk
case 1:
{
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"))
Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1)));
else if (lua.IsOfType(1, "Vector3"))
@ -560,7 +568,7 @@ namespace Ndk
case 2:
{
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"))
Nz::PlacementNew(vector, *static_cast<Nz::Vector2d*>(lua.ToUserdata(1)), lua.CheckNumber(2));
else

View File

@ -21,9 +21,9 @@ namespace Ndk
abstractSocketClass.BindMethod("QueryAvailableBytes", &Nz::AbstractSocket::QueryAvailableBytes);
/*********************************** 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;
switch (argCount)

View File

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

View File

@ -93,8 +93,10 @@ namespace Ndk
});
/*********************************** 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());
return true;
});

View File

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

View File

@ -216,6 +216,13 @@ namespace Ndk
m_forceRenderQueueInvalidation = false;
}
for (const Ndk::EntityHandle& particleGroup : m_particleGroups)
{
ParticleGroupComponent& groupComponent = particleGroup->GetComponent<ParticleGroupComponent>();
groupComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::Identity()); //< ParticleGroup doesn't use Matrix4f
}
camComponent.ApplyView();
Nz::SceneData sceneData;

View File

@ -2,6 +2,20 @@ version: '{branch}-rev{build}'
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:
- Visual Studio 2015
@ -16,5 +30,20 @@ configuration:
- DebugDynamic
- ReleaseDynamic
platform:
- Win32
- x64
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*")
flags("NoFramePointer")
optimize("Speed")
rtti("Off")
vectorextensions("SSE2")
configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"})
@ -228,6 +227,7 @@ function NazaraBuild:Execute()
targetdir("../lib/xcode/x64")
configuration("*Static")
defines("NAZARA_STATIC")
kind("StaticLib")
configuration("*Dynamic")
@ -242,6 +242,9 @@ function NazaraBuild:Execute()
configuration("DebugDynamic")
targetsuffix("-d")
configuration("Release*")
rtti(moduleTable.EnableRTTI and "On" or "Off")
configuration({})
files(moduleTable.Files)
@ -357,6 +360,12 @@ function NazaraBuild:Execute()
targetdir("../plugins/" .. toolTable.Name .. "/lib/xcode/x64")
end
configuration("*Static")
defines("NAZARA_STATIC")
configuration("Release*")
rtti(toolTable.EnableRTTI and "On" or "Off")
if (toolTable.Kind == "library" or toolTable.Kind == "plugin") then
configuration("*Static")
kind("StaticLib")
@ -430,6 +439,9 @@ function NazaraBuild:Execute()
includedirs(exampleTable.Includes)
links(exampleTable.Libraries)
configuration("Release*")
rtti(exampleTable.EnableRTTI and "On" or "Off")
configuration("x32")
libdirs(exampleTable.LibraryPaths.x86)
@ -705,7 +717,7 @@ function NazaraBuild:MakeInstallCommands(infoTable)
end
if (os.is("windows")) then
configuration({})
configuration("*Dynamic")
for k,v in pairs(self.InstallDir) do
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"
}
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 = {
"ws2_32"
}

View File

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

View File

@ -19,5 +19,6 @@ TOOL.Files = {
}
TOOL.Libraries = {
"NazaraNetwork",
"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/SerializationContext.hpp>
#include <functional>
#include <string>
#include <tuple>
#include <type_traits>
@ -38,11 +39,13 @@ namespace Nz
struct TypeTag {};
inline bool Serialize(SerializationContext& context, bool value);
inline bool Serialize(SerializationContext& context, const std::string& value);
template<typename T>
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, std::string* value);
template<typename T>
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 aussi à Freedom de siteduzero.com
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/AbstractHash.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Error.hpp>
@ -192,7 +193,7 @@ namespace Nz
/*!
* \ingroup core
* \brief Serializes a boolean
* \return true if serialization succedeed
* \return true if serialization succeeded
*
* \param context Context for the serialization
* \param value Boolean to serialize
@ -216,10 +217,26 @@ namespace Nz
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
* \brief Serializes an arithmetic type
* \return true if serialization succedeed
* \return true if serialization succeeded
*
* \param context Context for the serialization
* \param value Arithmetic type to serialize
@ -266,6 +283,23 @@ namespace Nz
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
* \brief Unserializes an arithmetic type

View File

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

View File

@ -2,8 +2,10 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <cstdlib>
#include <limits>
#include <utility>
#include <Nazara/Core/Debug.hpp>
@ -512,12 +514,117 @@ namespace Nz
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
*
* \param bitset Other bitset to swap
*/
template<typename Block, class Allocator>
void Bitset<Block, Allocator>::Swap(Bitset& bitset)
{
@ -763,6 +870,80 @@ namespace Nz
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
* \return A reference to this

View File

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

View File

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

View File

@ -7,7 +7,7 @@
#ifndef NAZARA_MEMORYHELPER_HPP
#define NAZARA_MEMORYHELPER_HPP
#if defined(NAZARA_COMPILER_MSVC)
#if defined(NAZARA_COMPILER_MSVC) || defined(NAZARA_COMPILER_MINGW)
#include <malloc.h>

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
@ -58,10 +58,14 @@
#include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPipeline.hpp>
#include <Nazara/Graphics/Model.hpp>
#include <Nazara/Graphics/ParticleController.hpp>
#include <Nazara/Graphics/ParticleDeclaration.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/ParticleGroup.hpp>
#include <Nazara/Graphics/ParticleMapper.hpp>
@ -77,5 +81,6 @@
#include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Graphics/TextureBackground.hpp>
#include <Nazara/Graphics/TileMap.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.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)
{
Renderer::SetTexture(availableTextureUnit, light.shadowMap);
Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler);
shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix);
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit);
if (uniforms.locations.lightViewProjMatrix != -1)
shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix);
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit);
}
else
else if (uniforms.locations.directionalSpotLightShadowMap != -1)
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;
}
@ -63,18 +69,22 @@ namespace Nz
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->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)
{
Renderer::SetTexture(availableTextureUnit, light.shadowMap);
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.directionalSpotLightShadowMap + index, dummyTexture);
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
break;
}
@ -88,19 +98,25 @@ namespace Nz
shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius));
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)
{
Renderer::SetTexture(availableTextureUnit, light.shadowMap);
Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler);
shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix);
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit);
if (uniforms.locations.lightViewProjMatrix != -1)
shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix);
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit);
}
else
else if (uniforms.locations.directionalSpotLightShadowMap != -1)
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;
}
@ -108,9 +124,14 @@ namespace Nz
}
else
{
shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
if (uniforms.locations.type != -1)
shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader
if (uniforms.locations.directionalSpotLightShadowMap != -1)
shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture);
if (uniforms.locations.pointLightShadowMap != -1)
shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap);
}
}

View File

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

View File

@ -41,6 +41,8 @@ namespace Nz
inline void DisableTiles();
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 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);
@ -55,6 +57,8 @@ namespace Nz
inline const Tile& GetTile(const Vector2ui& tilePos) const;
inline const Vector2f& GetTileSize() const;
inline bool IsIsometricModeEnabled() const;
inline void SetMaterial(std::size_t index, MaterialRef material);
inline TileMap& operator=(const TileMap& TileMap);
@ -87,6 +91,7 @@ namespace Nz
std::vector<Layer> m_layers;
Vector2ui m_mapSize;
Vector2f m_tileSize;
bool m_isometricModeEnabled;
static TileMapLibrary::LibraryMap s_library;
};

View File

@ -25,7 +25,8 @@ namespace Nz
m_tiles(mapSize.x * mapSize.y),
m_layers(materialCount),
m_mapSize(mapSize),
m_tileSize(tileSize)
m_tileSize(tileSize),
m_isometricModeEnabled(false)
{
NazaraAssert(m_tiles.size() != 0U, "Invalid map size");
NazaraAssert(m_tileSize.x != 0U && m_tileSize.y != 0U, "Invalid tile size");
@ -108,6 +109,22 @@ namespace Nz
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
*
@ -387,6 +404,17 @@ namespace Nz
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
*

View File

@ -28,7 +28,7 @@ namespace Nz
public:
using ClassFunc = std::function<int(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*)>;
using FinalizerFunc = std::function<bool(LuaInstance& lua, T& instance)>;
using StaticIndexFunc = std::function<bool(LuaInstance& lua)>;

View File

@ -19,9 +19,10 @@ namespace Nz
template<class T>
inline void LuaClass<T>::BindDefaultConstructor()
{
SetConstructor([] (Nz::LuaInstance& lua, T* instance)
SetConstructor([] (Nz::LuaInstance& lua, T* instance, std::size_t argumentCount)
{
NazaraUnused(lua);
NazaraUnused(argumentCount);
PlacementNew(instance);
return true;
@ -334,9 +335,11 @@ namespace Nz
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)));
if (!constructor(lua, instance))
if (!constructor(lua, instance, argCount))
{
lua.Error("Constructor failed");
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 :
m_memoryLimit(instance.m_memoryLimit),
m_memoryUsage(instance.m_memoryUsage),
m_timeLimit(m_timeLimit),
m_clock(std::move(m_clock)),
m_lastError(std::move(m_lastError)),
m_state(m_state),
m_level(m_level)
m_timeLimit(instance.m_timeLimit),
m_clock(std::move(instance.m_clock)),
m_lastError(std::move(instance.m_lastError)),
m_state(instance.m_state),
m_level(instance.m_level)
{
instance.m_state = nullptr;
}
@ -52,13 +52,13 @@ namespace Nz
inline LuaInstance& LuaInstance::operator=(LuaInstance&& instance) noexcept
{
m_clock = std::move(m_clock);
m_lastError = std::move(m_lastError);
m_level = m_level;
m_clock = std::move(instance.m_clock);
m_lastError = std::move(instance.m_lastError);
m_level = instance.m_level;
m_memoryLimit = instance.m_memoryLimit;
m_memoryUsage = instance.m_memoryUsage;
m_state = m_state;
m_timeLimit = m_timeLimit;
m_state = instance.m_state;
m_timeLimit = instance.m_timeLimit;
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"
// For conditions of distribution and use, see copyright notice in Config.hpp
#ifndef SIMPLEX_HPP
#define SIMPLE_HPP
#ifndef NAZARA_SIMPLEX_HPP
#define NAZARA_SIMPLEX_HPP
#include <Nazara/Prerequesites.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
#endif
// Version du moteur
// Nazara version macro
#define NAZARA_VERSION_MAJOR 0
#define NAZARA_VERSION_MINOR 1
#define NAZARA_VERSION_PATCH 1
#include <Nazara/Core/Config.hpp>
@ -97,7 +98,7 @@
#define NOMINMAX
#endif
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
// Version de Windows minimale : Vista
#define NAZARA_WINNT 0x0600
#else

View File

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

View File

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

View File

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

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.
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)).
Authors
-------
## Authors
Jérôme "Lynix" Leclercq - main developper (<lynix680@gmail.com>)
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.
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)
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)
- Submitting a patch to GitHub
- 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
- Doing anything else that might help us
Links
-----
[Website](http://www.digitalpulsesoftware.net)
[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki)
[Forum](http://forum.digitalpulsesoftware.net)
## Links
[Website](https://nazara.digitalpulsesoftware.net)
[Documentation](https://nazara.digitalpulsesoftware.net/doc)
[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
- **Fissal "DrFisher" Hannoun**: Helping a lot in architecture design
- **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.
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)).
Auteurs
-------
## Auteurs
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>)
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.
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***)
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é***)
- Soumettant un patch sur GitHub
- 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
- Faisant n'importe quoi d'autre qui pourrait nous aider
Liens
-----
[Website](http://www.digitalpulsesoftware.net)
[Wiki](https://github.com/DigitalPulseSoftware/NazaraEngine/wiki)
[Forum](http://forum.digitalpulsesoftware.net)
## Liens
[Website](https://nazara.digitalpulsesoftware.net)
[Documentation](https://nazara.digitalpulsesoftware.net/doc)
[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
- **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur
- **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])
{
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c
asm volatile ("cpuid" // Besoin d'être volatile ?
: "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output
: "a" (functionId), "c" (subFunctionId)); // input
// https://en.wikipedia.org/wiki/CPUID
asm volatile(
#ifdef NAZARA_PLATFORM_x64
"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
NazaraInternalError("Cpuid has been called although it is not supported");
#endif
@ -22,7 +34,7 @@ namespace Nz
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);
}
@ -37,7 +49,7 @@ namespace Nz
bool HardwareInfoImpl::IsCpuidSupported()
{
#ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits
return true; // cpuid is always supported on x64 arch
#else
#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
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
*
* \param lineSize Number of characters to read, if lineSize is 0, read as much as possible
*
* \remark Produces a NazaraWarning if cursor position could not be reset
* \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
*/
String Stream::ReadLine(unsigned int lineSize)
{
String line;
@ -71,19 +76,33 @@ namespace Nz
if (ptr)
{
std::ptrdiff_t pos = ptr - buffer;
if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos - 1] == '\r')
line.Append(buffer, pos - 1);
else
line.Append(buffer, pos);
if (ptr != buffer)
{
if (m_streamOptions & StreamOption_Text && buffer[pos - 1] == '\r')
line.Append(buffer, pos - 1);
else
line.Append(buffer, pos);
}
if (!SetCursorPos(GetCursorPos() - readSize + pos + 1))
NazaraWarning("Failed to reset cursos pos");
NazaraWarning("Failed to reset cursor pos");
break;
if (!line.IsEmpty())
break;
}
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);
}

View File

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

View File

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

View File

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

View File

@ -22,10 +22,22 @@ namespace Nz
// Visual propose une fonction intrinsèque pour le cpuid
__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)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c
asm volatile ("cpuid" // Besoin d'être volatile ?
: "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output
: "a" (functionId), "c" (subFunctionId)); // input
// https://en.wikipedia.org/wiki/CPUID
asm volatile(
#ifdef NAZARA_PLATFORM_x64
"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
NazaraInternalError("Cpuid has been called although it is not supported");
#endif
@ -33,7 +45,7 @@ namespace Nz
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;
GetNativeSystemInfo(&infos);
@ -52,7 +64,7 @@ namespace Nz
bool HardwareInfoImpl::IsCpuidSupported()
{
#ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits
return true; // cpuid is always supported on x64 arch
#else
#if defined(NAZARA_COMPILER_MSVC)
int supported;

View File

@ -469,6 +469,8 @@ namespace Nz
Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4);
}
while (billboardCount > 0);
billboardVector.clear();
}
}
}
@ -769,6 +771,7 @@ namespace Nz
}
}
}
instances.clear();
}
}
}

View File

@ -291,6 +291,7 @@ namespace Nz
declaration->EnableComponent(ParticleComponent_Normal, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, normal));
declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, position));
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));
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 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;
*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"
// 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 <netdb.h>
#include <netinet/in.h>
@ -30,3 +35,5 @@ namespace Nz
static ResolveError TranslateEAIErrorToResolveError(int error);
};
}
#endif // NAZARA_IPADDRESSIMPL_HPP

View File

@ -9,6 +9,7 @@
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <poll.h>
#include <unistd.h>
#include <cstring>
#include <Nazara/Network/Debug.hpp>
@ -397,6 +398,23 @@ namespace Nz
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)
{

View File

@ -2,12 +2,26 @@
// 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_SOCKETIMPL_HPP
#define NAZARA_SOCKETIMPL_HPP
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp>
#define NAZARA_NETWORK_POLL_SUPPORT 1
namespace Nz
{
struct PollSocket
{
SocketHandle fd;
short events;
short revents;
};
class SocketImpl
{
public:
@ -42,6 +56,8 @@ namespace Nz
static IpAddress QueryPeerAddress(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 ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
@ -66,3 +82,5 @@ namespace Nz
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)
{
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;
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received))

View File

@ -13,12 +13,12 @@ namespace Nz
{
namespace Detail
{
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
using addrinfoImpl = addrinfoW;
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)
@ -26,14 +26,14 @@ namespace Nz
std::array<wchar_t, NI_MAXHOST> hostnameBuffer;
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 (hostname)
hostname->Set(hostnameBuffer.data());
*hostname = std::move(String::Unicode(hostnameBuffer.data()));
if (service)
service->Set(serviceBuffer.data());
*service = std::move(String::Unicode(serviceBuffer.data()));
}
return result;
@ -105,7 +105,7 @@ namespace Nz
return IpAddress::Invalid;
}
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info)
{
switch (info->ai_family)

View File

@ -2,6 +2,11 @@
// 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_IPADDRESSIMPL_HPP
#define NAZARA_IPADDRESSIMPL_HPP
#include <Nazara/Network/IpAddress.hpp>
#include <winsock2.h>
#include <ws2tcpip.h>
@ -17,7 +22,7 @@ namespace Nz
~IpAddressImpl() = delete;
static IpAddress FromAddrinfo(const addrinfo* info);
#if NAZARA_CORE_WINDOWS_VISTA
#if NAZARA_CORE_WINDOWS_NT6
static IpAddress FromAddrinfo(const addrinfoW* info);
#endif
static IpAddress FromSockAddr(const sockaddr* address);
@ -33,3 +38,5 @@ namespace Nz
static ResolveError TranslateWSAErrorToResolveError(int error);
};
}
#endif // NAZARA_IPADDRESSIMPL_HPP

View File

@ -7,18 +7,21 @@
#include <Nazara/Core/Log.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
// Define them ourself for now
struct tcp_keepalive
{
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
#else
#include <Mstcpip.h>
#endif
#include <Winsock2.h>
#include <Nazara/Network/Debug.hpp>
@ -412,6 +415,34 @@ namespace Nz
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)
{

View File

@ -2,13 +2,27 @@
// 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_SOCKETIMPL_HPP
#define NAZARA_SOCKETIMPL_HPP
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <winsock2.h>
#define NAZARA_NETWORK_POLL_SUPPORT NAZARA_CORE_WINDOWS_NT6
namespace Nz
{
struct PollSocket
{
SocketHandle fd;
short events;
short revents;
};
class SocketImpl
{
public:
@ -43,6 +57,8 @@ namespace Nz
static IpAddress QueryPeerAddress(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 ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
@ -66,3 +82,5 @@ namespace Nz
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

@ -76,7 +76,7 @@ namespace Nz
code << "#define GLSL_VERSION " << glslVersion << "\n\n";
code << "#define EARLY_FRAGMENT_TEST " << (glslVersion >= 420 || OpenGL::IsSupported(OpenGLExtension_Shader_ImageLoadStore)) << "\n\n";
code << "#define EARLY_FRAGMENT_TEST " << ((glslVersion >= 420 || OpenGL::IsSupported(OpenGLExtension_Shader_ImageLoadStore)) ? '1' : '0') << "\n\n";
for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it)
code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n';

View File

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

View File

@ -13,9 +13,87 @@
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)
{
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;
@ -31,9 +109,6 @@ namespace Nz
String matName, meshName;
matName = meshName = "default";
m_errorCount = 0;
m_keepLastLine = false;
m_lineCount = 0;
m_meshes.clear();
m_mtlLib.Clear();

View File

@ -1284,6 +1284,9 @@ namespace Nz
bool PixelFormat::Initialize()
{
Bitset<> b32(0xFFFFFFFF);
b32.Resize(128);
// Setup informations about every pixel format
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);
@ -1317,18 +1320,18 @@ namespace Nz
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_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_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGB32UI] = PixelFormatInfo("RGB32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned);
s_pixelFormatInfos[PixelFormatType_RGB32F] = PixelFormatInfo("RGB32F", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Float);
s_pixelFormatInfos[PixelFormatType_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, 0, PixelFormatSubType_Int);
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_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_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_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_RGBA32I] = PixelFormatInfo("RGBA32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int);
s_pixelFormatInfos[PixelFormatType_RGBA32UI] = PixelFormatInfo("RGBA32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned);
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, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Int);
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_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);

View File

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

View File

@ -29,6 +29,11 @@ namespace Nz
Window* fullscreenWindow = nullptr;
}
Window::~Window()
{
Destroy();
}
bool Window::Create(VideoMode mode, const String& title, UInt32 style)
{
// 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/X11/Display.hpp>
#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>
namespace Nz

View File

@ -15,12 +15,12 @@ SCENARIO("Model", "[GRAPHICS][MODEL]")
Nz::ModelRef model = Nz::Model::New();
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->GetSkinCount() == 1);
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);
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")
{
Nz::UInt16 port = 64266;
// Disabled for now
/*Nz::UInt16 port = 64266;
Nz::RUdpConnection server;
REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port));
Nz::IpAddress serverIP = server.GetBoundAddress();
Nz::IpAddress serverIP(Nz::IpAddress::LoopbackIpV4.ToIPv4(), port);
REQUIRE(serverIP.IsValid());
Nz::RUdpConnection client;
REQUIRE(client.Listen(Nz::NetProtocol_IPv4, port + 1));
Nz::IpAddress clientIP = client.GetBoundAddress();
REQUIRE(client.Connect(serverIP));
REQUIRE(clientIP.IsValid());
@ -30,11 +35,13 @@ SCENARIO("RUdpConnection", "[NETWORK][RUDPCONNECTION]")
{
Nz::RUdpMessage rudpMessage;
server.Update();
REQUIRE(server.PollMessage(&rudpMessage));
Nz::Vector3f result;
rudpMessage.data >> result;
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,36 @@
#include <Nazara/Core/Thread.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/TcpClient.hpp>
#include <Nazara/Network/TcpServer.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <random>
SCENARIO("TCP", "[NETWORK][TCP]")
{
GIVEN("Two TCP, one client, one server")
{
// Avoid reusing the same socket
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1025, 64245);
std::uniform_int_distribution<Nz::UInt16> dis(1025, 65535);
Nz::UInt16 port = dis(rd);
Nz::UInt16 port = dis(gen);
Nz::TcpServer server;
server.EnableBlocking(false);
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());
Nz::TcpClient client;
REQUIRE(client.Connect(serverIP) == Nz::SocketState_Connecting);
Nz::IpAddress clientIP = client.GetRemoteAddress();
REQUIRE(clientIP.IsValid());
Nz::Thread::Sleep(100);
Nz::TcpClient 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/Network/UdpSocket.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Catch/catch.hpp>
#include <random>
SCENARIO("UdpSocket", "[NETWORK][UDPSOCKET]")
{
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);
REQUIRE(server.Bind(port) == Nz::SocketState_Bound);
Nz::IpAddress serverIP = server.GetBoundAddress();
Nz::IpAddress serverIP(Nz::IpAddress::LoopbackIpV4.ToIPv4(), port);
REQUIRE(serverIP.IsValid());
Nz::UdpSocket client(Nz::NetProtocol_IPv4);
REQUIRE(client.Bind(port + 1) == Nz::SocketState_Bound);
Nz::IpAddress clientIP = client.GetBoundAddress();
REQUIRE(clientIP.IsValid());
@ -30,6 +36,7 @@ SCENARIO("UdpSocket", "[NETWORK][UDPSOCKET]")
Nz::NetPacket resultPacket;
Nz::IpAddress fromIp;
REQUIRE(server.ReceivePacket(&resultPacket, &fromIp));
Nz::Vector3f result;
resultPacket >> result;
REQUIRE(result == vector123);

View File

@ -5,17 +5,20 @@ SCENARIO("Application", "[NDK][APPLICATION]")
{
GIVEN("An application")
{
Ndk::Application application;
application.AddWorld();
Nz::Window& window = application.AddWindow<Nz::Window>();
Nz::Window& window = Ndk::Application::Instance()->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>
{
public:
TestComponent(int value) :
m_value(value)
{
}
int GetValue() const
{
return m_value;
}
int m_value;
static Ndk::ComponentIndex componentIndex;
};
@ -16,7 +28,7 @@ SCENARIO("Component", "[NDK][COMPONENT]")
{
GIVEN("Our TestComponent")
{
TestComponent testComponent;
TestComponent testComponent(42);
WHEN("We clone it")
{
@ -24,7 +36,7 @@ SCENARIO("Component", "[NDK][COMPONENT]")
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>
{
public:
TestSystem()
TestSystem(int value) :
m_value(value)
{
}
int GetValue() const
{
return m_value;
}
~TestSystem() = default;
static Ndk::SystemIndex systemIndex;
private:
int m_value;
void OnUpdate(float elapsedTime) override
{
}
@ -27,7 +35,7 @@ SCENARIO("System", "[NDK][SYSTEM]")
{
GIVEN("Our TestSystem")
{
TestSystem testSystem;
TestSystem testSystem(666);
WHEN("We clone it")
{
@ -35,7 +43,7 @@ SCENARIO("System", "[NDK][SYSTEM]")
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
#include <Catch/catch.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Core/Core.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <NDK/Application.hpp>
#include <Nazara/Core/Log.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);