Split engine to packages NazaraUtils and NZSL (#375)

* Move code to NazaraUtils and NZSL packages

* Reorder includes

* Tests: Remove glslang and spirv-tools deps

* Tests: Remove glslang init

* Remove NazaraUtils tests and fix Vector4Test

* Fix Linux compilation

* Update msys2-build.yml

* Fix assimp package

* Update xmake.lua

* Update xmake.lua

* Fix shader compilation on MinGW

* Final fixes

* The final fix 2: the fix strikes back!

* Disable cache on CI

* The return of the fix™️
This commit is contained in:
Jérôme Leclercq 2022-05-25 19:36:10 +02:00 committed by GitHub
parent 3f8f1c4653
commit 03e2801dbe
483 changed files with 1139 additions and 59112 deletions

View File

@ -89,7 +89,7 @@ jobs:
# Setup compilation mode and install project dependencies
- name: Configure xmake and install dependencies
run: xmake config --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.config.arch }} --mode=coverage --yes
run: xmake config --ccache=n --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.config.arch }} --mode=coverage --yes
# Build the engine
- name: Build Nazara

View File

@ -68,7 +68,7 @@ jobs:
# Setup compilation mode and install project dependencies
- name: Configure xmake and install dependencies
run: xmake config --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
run: xmake config --ccache=n --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
# Build the engine
- name: Build Nazara

View File

@ -62,7 +62,7 @@ jobs:
# Setup compilation mode and install project dependencies
- name: Configure xmake and install dependencies
run: xmake config --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
run: xmake config --ccache=n --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
# Build the engine
- name: Build Nazara

View File

@ -92,7 +92,7 @@ jobs:
# Setup compilation mode and install project dependencies
- name: Configure xmake and install dependencies
run: xmake config --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
run: xmake config --ccache=n --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
# Build the engine
- name: Build Nazara

View File

@ -62,7 +62,7 @@ jobs:
# Setup compilation mode and install project dependencies
- name: Configure xmake and install dependencies
run: xmake.exe config --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
run: xmake.exe config --ccache=n --shadernodes=y --tests=y --unitybuild=y --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes
# Build the engine
- name: Build Nazara

View File

@ -3,8 +3,9 @@
#include <Nazara/Math/Angle.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp>
#include <Nazara/Utility.hpp>
#include <NZSL/FieldOffsets.hpp>
#include <NZSL/ShaderLangParser.hpp>
#include <array>
#include <iostream>
#include <random>
@ -77,7 +78,7 @@ int main()
Nz::Modules<Nz::Graphics> nazara(rendererConfig);
Nz::ShaderWriter::States states;
nzsl::ShaderWriter::States states;
states.shaderModuleResolver = Nz::Graphics::Instance()->GetShaderModuleResolver();
Nz::RenderWindow window;
@ -136,13 +137,13 @@ int main()
skyboxPipelineLayoutInfo.bindings.push_back({
0, 0,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType_All
nzsl::ShaderStageType_All
});
auto& textureBinding = skyboxPipelineLayoutInfo.bindings.emplace_back();
textureBinding.setIndex = 0;
textureBinding.bindingIndex = 1;
textureBinding.shaderStageFlags = Nz::ShaderStageType::Fragment;
textureBinding.shaderStageFlags = nzsl::ShaderStageType::Fragment;
textureBinding.type = Nz::ShaderBindingType::Texture;
std::shared_ptr<Nz::RenderPipelineLayout> skyboxPipelineLayout = device->InstantiateRenderPipelineLayout(std::move(skyboxPipelineLayoutInfo));
@ -153,7 +154,7 @@ int main()
skyboxPipelineInfo.faceCulling = true;
skyboxPipelineInfo.cullingSide = Nz::FaceSide::Front;
skyboxPipelineInfo.pipelineLayout = skyboxPipelineLayout;
skyboxPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "skybox.nzsl", states));
skyboxPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "skybox.nzsl", states));
skyboxPipelineInfo.vertexBuffers.push_back({
0,
meshPrimitiveParams.vertexDeclaration
@ -186,8 +187,8 @@ int main()
auto customSettings = Nz::BasicMaterial::GetSettings()->GetBuilderData();
customSettings.shaders.clear();
customSettings.shaders.emplace_back(std::make_shared<Nz::UberShader>(Nz::ShaderStageType::Fragment, Nz::ShaderLang::ParseFromFile(resourceDir / "deferred_frag.nzsl")));
customSettings.shaders.emplace_back(std::make_shared<Nz::UberShader>(Nz::ShaderStageType::Vertex, Nz::ShaderLang::ParseFromFile(resourceDir / "deferred_vert.nzsl")));
customSettings.shaders.emplace_back(std::make_shared<Nz::UberShader>(nzsl::ShaderStageType::Fragment, nzsl::ParseFromFile(resourceDir / "deferred_frag.nzsl")));
customSettings.shaders.emplace_back(std::make_shared<Nz::UberShader>(nzsl::ShaderStageType::Vertex, nzsl::ParseFromFile(resourceDir / "deferred_vert.nzsl")));
auto customMatSettings = std::make_shared<Nz::MaterialSettings>(std::move(customSettings));
@ -269,7 +270,7 @@ int main()
lightingPipelineLayoutInfo.bindings.push_back({
0, 0,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType_All
nzsl::ShaderStageType_All
});
for (unsigned int i = 0; i < 3; ++i)
@ -278,7 +279,7 @@ int main()
0,
i + 1,
Nz::ShaderBindingType::Texture,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
});
}
@ -286,15 +287,15 @@ int main()
1,
0,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex,
nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex,
});
/*Nz::FieldOffsets pointLightOffsets(Nz::StructLayout::Std140);
std::size_t colorOffset = pointLightOffsets.AddField(Nz::StructFieldType::Float3);
std::size_t positionOffset = pointLightOffsets.AddField(Nz::StructFieldType::Float3);
std::size_t constantOffset = pointLightOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t linearOffset = pointLightOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t quadraticOffset = pointLightOffsets.AddField(Nz::StructFieldType::Float1);
/*nzsl::FieldOffsets pointLightOffsets(nzsl::StructLayout::Std140);
std::size_t colorOffset = pointLightOffsets.AddField(nzsl::StructFieldType::Float3);
std::size_t positionOffset = pointLightOffsets.AddField(nzsl::StructFieldType::Float3);
std::size_t constantOffset = pointLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t linearOffset = pointLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t quadraticOffset = pointLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t alignedPointLightSize = Nz::Align(pointLightOffsets.GetSize(), static_cast<std::size_t>(deviceInfo.limits.minUniformBufferOffsetAlignment));*/
@ -315,15 +316,15 @@ int main()
}
*/
Nz::FieldOffsets spotLightOffsets(Nz::StructLayout::Std140);
std::size_t transformMatrixOffset = spotLightOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true);
std::size_t colorOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float3);
std::size_t positionOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float3);
std::size_t directionOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float3);
std::size_t radiusOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t invRadiusOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t innerAngleOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t outerAngleOffset = spotLightOffsets.AddField(Nz::StructFieldType::Float1);
nzsl::FieldOffsets spotLightOffsets(nzsl::StructLayout::Std140);
std::size_t transformMatrixOffset = spotLightOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true);
std::size_t colorOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float3);
std::size_t positionOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float3);
std::size_t directionOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float3);
std::size_t radiusOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t invRadiusOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t innerAngleOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t outerAngleOffset = spotLightOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t alignedSpotLightSize = Nz::Align(spotLightOffsets.GetAlignedSize(), static_cast<std::size_t>(deviceInfo.limits.minUniformBufferOffsetAlignment));
@ -367,13 +368,13 @@ int main()
fullscreenPipelineLayoutInfoViewer.bindings.push_back({
0, 0,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType_All
nzsl::ShaderStageType_All
});
fullscreenPipelineLayoutInfoViewer.bindings.push_back({
0, 1,
Nz::ShaderBindingType::Texture,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
});
Nz::RenderPipelineInfo fullscreenPipelineInfoViewer;
@ -384,7 +385,7 @@ int main()
fullscreenVertexDeclaration
});
fullscreenPipelineInfoViewer.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_bright.nzsl", states));
fullscreenPipelineInfoViewer.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_bright.nzsl", states));
std::shared_ptr<Nz::ShaderBinding> bloomBrightShaderBinding;
@ -397,18 +398,18 @@ int main()
gaussianBlurPipelineLayoutInfo.bindings.push_back({
0, 2,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
});
Nz::RenderPipelineInfo gaussianBlurPipelineInfo = fullscreenPipelineInfoViewer;
gaussianBlurPipelineInfo.pipelineLayout = device->InstantiateRenderPipelineLayout(gaussianBlurPipelineLayoutInfo);
Nz::FieldOffsets gaussianBlurDataOffsets(Nz::StructLayout::Std140);
std::size_t gaussianBlurDataDirection = gaussianBlurDataOffsets.AddField(Nz::StructFieldType::Float2);
std::size_t gaussianBlurDataSize = gaussianBlurDataOffsets.AddField(Nz::StructFieldType::Float1);
nzsl::FieldOffsets gaussianBlurDataOffsets(nzsl::StructLayout::Std140);
std::size_t gaussianBlurDataDirection = gaussianBlurDataOffsets.AddField(nzsl::StructFieldType::Float2);
std::size_t gaussianBlurDataSize = gaussianBlurDataOffsets.AddField(nzsl::StructFieldType::Float1);
gaussianBlurPipelineInfo.shaderModules.clear();
gaussianBlurPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gaussian_blur.nzsl", states));
gaussianBlurPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gaussian_blur.nzsl", states));
std::shared_ptr<Nz::RenderPipeline> gaussianBlurPipeline = device->InstantiateRenderPipeline(gaussianBlurPipelineInfo);
std::vector<std::shared_ptr<Nz::ShaderBinding>> gaussianBlurShaderBinding(BloomSubdivisionCount * 2);
@ -438,7 +439,7 @@ int main()
std::shared_ptr<Nz::ShaderBinding> toneMappingShaderBinding;
fullscreenPipelineInfoViewer.shaderModules.clear();
fullscreenPipelineInfoViewer.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "tone_mapping.nzsl", states));
fullscreenPipelineInfoViewer.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "tone_mapping.nzsl", states));
std::shared_ptr<Nz::RenderPipeline> toneMappingPipeline = device->InstantiateRenderPipeline(fullscreenPipelineInfoViewer);
@ -450,19 +451,19 @@ int main()
bloomBlendPipelineLayoutInfo.bindings.push_back({
0, 0,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType_All
nzsl::ShaderStageType_All
});
/*bloomBlendPipelineLayoutInfo.bindings.push_back({
0, 1,
Nz::ShaderBindingType::Texture,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
});*/
bloomBlendPipelineLayoutInfo.bindings.push_back({
0, 2,
Nz::ShaderBindingType::Texture,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
});
@ -477,7 +478,7 @@ int main()
fullscreenVertexDeclaration
});
bloomBlendPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_final.nzsl", states));
bloomBlendPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "bloom_final.nzsl", states));
std::shared_ptr<Nz::RenderPipeline> bloomBlendPipeline = device->InstantiateRenderPipeline(bloomBlendPipelineInfo);
@ -490,7 +491,7 @@ int main()
fullscreenPipelineLayoutInfo.bindings.push_back({
0, 0,
Nz::ShaderBindingType::Texture,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
});
Nz::RenderPipelineInfo fullscreenPipelineInfo;
@ -501,7 +502,7 @@ int main()
fullscreenVertexDeclaration
});
fullscreenPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gamma.nzsl", states));
fullscreenPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "gamma.nzsl", states));
// God rays
@ -512,17 +513,17 @@ int main()
{
0, 0,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
},
{
0, 1,
Nz::ShaderBindingType::UniformBuffer,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
},
{
0, 2,
Nz::ShaderBindingType::Texture,
Nz::ShaderStageType::Fragment,
nzsl::ShaderStageType::Fragment,
},
}
};
@ -535,16 +536,16 @@ int main()
fullscreenVertexDeclaration
});
godraysPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "god_rays.nzsl", states));
godraysPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "god_rays.nzsl", states));
std::shared_ptr<Nz::RenderPipeline> godraysPipeline = device->InstantiateRenderPipeline(godraysPipelineInfo);
Nz::FieldOffsets godraysFieldOffsets(Nz::StructLayout::Std140);
std::size_t gr_exposureOffset = godraysFieldOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t gr_decayOffset = godraysFieldOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t gr_densityOffset = godraysFieldOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t gr_weightOffset = godraysFieldOffsets.AddField(Nz::StructFieldType::Float1);
std::size_t gr_lightPositionOffset = godraysFieldOffsets.AddField(Nz::StructFieldType::Float2);
nzsl::FieldOffsets godraysFieldOffsets(nzsl::StructLayout::Std140);
std::size_t gr_exposureOffset = godraysFieldOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t gr_decayOffset = godraysFieldOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t gr_densityOffset = godraysFieldOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t gr_weightOffset = godraysFieldOffsets.AddField(nzsl::StructFieldType::Float1);
std::size_t gr_lightPositionOffset = godraysFieldOffsets.AddField(nzsl::StructFieldType::Float2);
std::shared_ptr<Nz::ShaderBinding> godRaysShaderBinding = godraysPipelineInfo.pipelineLayout->AllocateShaderBinding(0);
@ -590,7 +591,7 @@ int main()
lightingPipelineInfo.stencilBack.depthFail = Nz::StencilOperation::Zero;
lightingPipelineInfo.stencilBack.pass = Nz::StencilOperation::Zero;
lightingPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "lighting.nzsl", states));
lightingPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "lighting.nzsl", states));
std::shared_ptr<Nz::RenderPipeline> lightingPipeline = device->InstantiateRenderPipeline(lightingPipelineInfo);
@ -612,7 +613,7 @@ int main()
stencilPipelineInfo.stencilBack.compare = Nz::RendererComparison::Always;
stencilPipelineInfo.stencilBack.depthFail = Nz::StencilOperation::Invert;
stencilPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "lighting.nzsl", states));
stencilPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(nzsl::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "lighting.nzsl", states));
std::shared_ptr<Nz::RenderPipeline> stencilPipeline = device->InstantiateRenderPipeline(stencilPipelineInfo);

View File

@ -2,9 +2,8 @@
#include <Nazara/Platform.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <Nazara/Shader/SpirvPrinter.hpp>
#include <NZSL/SpirvConstantCache.hpp>
#include <NZSL/SpirvPrinter.hpp>
#include <Nazara/Utility.hpp>
#include <array>
#include <iostream>

View File

@ -9,9 +9,8 @@
#include <Nazara/Physics2D/Components.hpp>
#include <Nazara/Physics2D/Systems.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <Nazara/Shader/SpirvPrinter.hpp>
#include <NZSL/SpirvConstantCache.hpp>
#include <NZSL/SpirvPrinter.hpp>
#include <Nazara/Utility.hpp>
#include <Nazara/Utility/Components.hpp>
#include <Nazara/Widgets.hpp>
@ -92,6 +91,7 @@ int main()
sprite->SetOrigin({ 16.f, 16.f, 0.f });
registry.emplace<Nz::NodeComponent>(spriteEntity).SetPosition(1920 / 2 + x * 36.f, 1080 / 2 + y * 36.f);
registry.emplace<Nz::GraphicsComponent>(spriteEntity).AttachRenderable(sprite, 1);
auto& rigidBody = registry.emplace<Nz::RigidBody2DComponent>(spriteEntity, physSytem.CreateRigidBody(50.f, std::make_shared<Nz::BoxCollider2D>(Nz::Vector2f(32.f, 32.f))));
rigidBody.SetElasticity(0.99f);

View File

@ -9,9 +9,8 @@
#include <Nazara/Physics3D/Components.hpp>
#include <Nazara/Physics3D/Systems.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <Nazara/Shader/SpirvPrinter.hpp>
#include <NZSL/SpirvConstantCache.hpp>
#include <NZSL/SpirvPrinter.hpp>
#include <Nazara/Utility.hpp>
#include <Nazara/Utility/Components.hpp>
#include <entt/entt.hpp>

View File

@ -1,8 +1,11 @@
#include <Nazara/Core.hpp>
#include <Nazara/Math.hpp>
#include <Nazara/Platform.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp>
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
#include <NZSL/FilesystemModuleResolver.hpp>
#include <NZSL/LangWriter.hpp>
#include <NZSL/ShaderLangParser.hpp>
#include <NZSL/Ast/SanitizeVisitor.hpp>
#include <Nazara/Utility.hpp>
#include <array>
#include <iostream>
@ -11,7 +14,6 @@ NAZARA_REQUEST_DEDICATED_GPU()
const char barModuleSource[] = R"(
[nzsl_version("1.0")]
[uuid("4BB09DEE-F70A-442E-859F-E8F2F3F8583D")]
module Test.Bar;
fn dummy() {}
@ -25,7 +27,6 @@ struct Bar
const char dataModuleSource[] = R"(
[nzsl_version("1.0")]
[uuid("E49DC9AD-469C-462C-9719-A6F012372029")]
module Test.Data;
import Test.Bar;
@ -133,36 +134,36 @@ int main()
return __LINE__;
}
Nz::ShaderAst::ModulePtr shaderModule = Nz::ShaderLang::Parse(std::string_view(shaderSource, sizeof(shaderSource)));
nzsl::Ast::ModulePtr shaderModule = nzsl::Parse(std::string_view(shaderSource, sizeof(shaderSource)));
if (!shaderModule)
{
std::cout << "Failed to parse shader module" << std::endl;
return __LINE__;
}
auto directoryModuleResolver = std::make_shared<Nz::FilesystemModuleResolver>();
auto directoryModuleResolver = std::make_shared<nzsl::FilesystemModuleResolver>();
directoryModuleResolver->RegisterModule(std::string_view(barModuleSource));
directoryModuleResolver->RegisterModule(std::string_view(dataModuleSource));
Nz::ShaderAst::SanitizeVisitor::Options sanitizeOpt;
nzsl::Ast::SanitizeVisitor::Options sanitizeOpt;
sanitizeOpt.moduleResolver = directoryModuleResolver;
shaderModule = Nz::ShaderAst::Sanitize(*shaderModule, sanitizeOpt);
shaderModule = nzsl::Ast::Sanitize(*shaderModule, sanitizeOpt);
if (!shaderModule)
{
std::cout << "Failed to compile shader module" << std::endl;
return __LINE__;
}
Nz::LangWriter langWriter;
nzsl::LangWriter langWriter;
std::string output = langWriter.Generate(*shaderModule);
std::cout << output << std::endl;
assert(Nz::ShaderAst::Sanitize(*Nz::ShaderLang::Parse(output)));
assert(nzsl::Ast::Sanitize(*nzsl::Parse(output)));
Nz::ShaderWriter::States states;
nzsl::ShaderWriter::States states;
states.optimize = true;
auto fragVertShader = device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, *shaderModule, states);
auto fragVertShader = device->InstantiateShaderModule(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, *shaderModule, states);
if (!fragVertShader)
{
std::cout << "Failed to instantiate shader" << std::endl;
@ -221,7 +222,7 @@ int main()
auto& uboBinding = pipelineLayoutInfo.bindings.emplace_back();
uboBinding.setIndex = 0;
uboBinding.bindingIndex = 0;
uboBinding.shaderStageFlags = Nz::ShaderStageType::Vertex;
uboBinding.shaderStageFlags = nzsl::ShaderStageType::Vertex;
uboBinding.type = Nz::ShaderBindingType::UniformBuffer;
std::shared_ptr<Nz::RenderPipelineLayout> basePipelineLayout = device->InstantiateRenderPipelineLayout(pipelineLayoutInfo);
@ -229,7 +230,7 @@ int main()
auto& textureBinding = pipelineLayoutInfo.bindings.emplace_back();
textureBinding.setIndex = 1;
textureBinding.bindingIndex = 0;
textureBinding.shaderStageFlags = Nz::ShaderStageType::Fragment;
textureBinding.shaderStageFlags = nzsl::ShaderStageType::Fragment;
textureBinding.type = Nz::ShaderBindingType::Texture;
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = device->InstantiateRenderPipelineLayout(std::move(pipelineLayoutInfo));

View File

@ -2,7 +2,7 @@
#include <Nazara/OpenGLRenderer.hpp>
#include <Nazara/OpenGLRenderer/Wrapper.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader/FieldOffsets.hpp>
#include <NZSL/FieldOffsets.hpp>
#include <iostream>
#include <numeric>
@ -136,16 +136,16 @@ int main()
std::vector<std::size_t> computedOffsets;
Nz::FieldOffsets fieldOffsets(Nz::StructLayout::Std140);
computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(Nz::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddField(Nz::StructFieldType::Float2));
computedOffsets.push_back(fieldOffsets.AddField(Nz::StructFieldType::Float2));
computedOffsets.push_back(fieldOffsets.AddField(Nz::StructFieldType::Float3));
nzsl::FieldOffsets fieldOffsets(nzsl::StructLayout::Std140);
computedOffsets.push_back(fieldOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddMatrix(nzsl::StructFieldType::Float1, 4, 4, true));
computedOffsets.push_back(fieldOffsets.AddField(nzsl::StructFieldType::Float2));
computedOffsets.push_back(fieldOffsets.AddField(nzsl::StructFieldType::Float2));
computedOffsets.push_back(fieldOffsets.AddField(nzsl::StructFieldType::Float3));
GLint dataSize;

View File

@ -9,9 +9,8 @@
#include <Nazara/Physics3D/Components.hpp>
#include <Nazara/Physics3D/Systems.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp>
#include <Nazara/Shader/SpirvPrinter.hpp>
#include <NZSL/SpirvConstantCache.hpp>
#include <NZSL/SpirvPrinter.hpp>
#include <Nazara/Utility.hpp>
#include <Nazara/Utility/Components.hpp>
#include <Nazara/Widgets.hpp>

View File

@ -10,9 +10,10 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/Enums.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <memory>
namespace Nz

View File

@ -7,7 +7,7 @@
#ifndef NAZARA_AUDIO_ENUMS_HPP
#define NAZARA_AUDIO_ENUMS_HPP
#include <cstdint>
#include <cstddef>
namespace Nz
{

View File

@ -15,7 +15,7 @@
#include <Nazara/Audio/Enums.hpp>
#include <Nazara/Audio/OpenAL.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
#include <array>
#include <string>

View File

@ -32,43 +32,34 @@
#include <Nazara/Core/AbstractHash.hpp>
#include <Nazara/Core/AbstractLogger.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/ByteArrayPool.hpp>
#include <Nazara/Core/ByteStream.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/Core/EmptyStream.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/FileLogger.hpp>
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Core/Functor.hpp>
#include <Nazara/Core/GuillotineBinPack.hpp>
#include <Nazara/Core/HandledObject.hpp>
#include <Nazara/Core/HardwareInfo.hpp>
#include <Nazara/Core/Initializer.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MemoryManager.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Core/MemoryStream.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Core/ModuleBase.hpp>
#include <Nazara/Core/Modules.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/MovableValue.hpp>
#include <Nazara/Core/ObjectHandle.hpp>
#include <Nazara/Core/ObjectLibrary.hpp>
#include <Nazara/Core/ObjectRef.hpp>
#include <Nazara/Core/OffsetOf.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Core/PluginManager.hpp>
#include <Nazara/Core/PoolByteStream.hpp>
@ -81,16 +72,10 @@
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Core/ResourceSaver.hpp>
#include <Nazara/Core/SerializationContext.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/SparsePtr.hpp>
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/Core/StdLogger.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Core/TaskScheduler.hpp>
#include <Nazara/Core/TypeList.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Core/Unicode.hpp>
#include <Nazara/Core/Updatable.hpp>
#include <Nazara/Core/Uuid.hpp>

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_ABSTRACTHASH_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <memory>

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_ABSTRACTLOGGER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <string>

View File

@ -11,7 +11,8 @@
#include <Nazara/Core/AbstractHash.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/SerializationContext.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Utils/Algorithm.hpp>
#include <Nazara/Utils/TypeTag.hpp>
#include <functional>
#include <string>
#include <tuple>
@ -22,74 +23,10 @@ namespace Nz
{
class ByteArray;
template<typename T> decltype(auto) AccessByOffset(void* basePtr, std::size_t offset);
template<typename T> decltype(auto) AccessByOffset(const void* basePtr, std::size_t offset);
template<typename T> constexpr T Align(T offset, T alignment);
template<typename T> constexpr T AlignPow2(T offset, T alignment);
template<typename F, typename Tuple> decltype(auto) Apply(F&& fn, Tuple&& t);
template<typename O, typename F, typename Tuple> decltype(auto) Apply(O& object, F&& fn, Tuple&& t);
template<typename T> constexpr std::size_t BitCount();
template<typename T> ByteArray ComputeHash(HashType hash, const T& v);
template<typename T> ByteArray ComputeHash(AbstractHash& hash, const T& v);
template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept;
template<typename T> std::size_t CountOf(const T& c);
constexpr UInt32 CRC32(const UInt8* data, std::size_t size) noexcept;
constexpr UInt32 CRC32(const char* str) noexcept;
constexpr UInt32 CRC32(const std::string_view& str) noexcept;
template<std::size_t N> constexpr std::size_t CountOf(const char(&str)[N]) noexcept;
inline bool HashAppend(AbstractHash* hash, const std::string_view& v);
template<typename T> void HashCombine(std::size_t& seed, const T& v);
template<typename T> bool IsPowerOfTwo(T value);
template<typename K, typename V> V& Retrieve(std::unordered_map<K, V>& map, const K& key);
template<typename K, typename V> const V& Retrieve(const std::unordered_map<K, V>& map, const K& key);
template<typename T> T ReverseBits(T integer);
template<typename To, typename From> To SafeCast(From&& value);
template<typename T, typename U>std::unique_ptr<T> StaticUniquePointerCast(std::unique_ptr<U>&& ptr);
template<typename T> constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>;
template<typename T>
struct AlwaysFalse : std::false_type {};
// Helper for std::visit
template<typename... Ts> struct Overloaded : Ts...
{
using Ts::operator()...;
};
template<typename... Ts> Overloaded(Ts...) -> Overloaded<Ts...>;
template<typename... Args>
struct OverloadResolver
{
template<typename R, typename T>
constexpr auto operator()(R(T::* ptr)(Args...)) const noexcept
{
return ptr;
}
template<typename R, typename T>
constexpr auto operator()(R(T::* ptr)(Args...) const) const noexcept
{
return ptr;
}
template<typename R>
constexpr auto operator()(R(*ptr)(Args...)) const noexcept
{
return ptr;
}
};
template<typename... Args> constexpr OverloadResolver<Args...> Overload = {};
template<typename T>
struct PointedType
{
using type = void; //< FIXME: I can't make SFINAE work
};
template<typename T>
using Pointer = T*;
template<typename T>
bool Serialize(SerializationContext& context, T&& value);

View File

@ -2,10 +2,6 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// http://stackoverflow.com/questions/687490/c0x-how-do-i-expand-a-tuple-into-variadic-template-function-arguments
// 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>
@ -21,193 +17,6 @@
namespace Nz
{
namespace Detail
{
// http://www.cppsamples.com/common-tasks/apply-tuple-to-function.html
template<typename F, typename Tuple, size_t... S>
decltype(auto) ApplyImplFunc(F&& fn, Tuple&& t, std::index_sequence<S...>)
{
return std::forward<F>(fn)(std::get<S>(std::forward<Tuple>(t))...);
}
template<typename O, typename F, typename Tuple, size_t... S>
decltype(auto) ApplyImplMethod(O& object, F&& fn, Tuple&& t, std::index_sequence<S...>)
{
return (object .* std::forward<F>(fn))(std::get<S>(std::forward<Tuple>(t))...);
}
NAZARA_CORE_API extern const UInt8 BitReverseTable256[256];
// https://stackoverflow.com/questions/28675727/using-crc32-algorithm-to-hash-string-at-compile-time
// Generates CRC-32 table, algorithm based from this link:
// http://www.hackersdelight.org/hdcodetxt/crc.c.txt
constexpr auto GenerateCRC32Table(UInt32 polynomial = 0xEDB88320)
{
#ifdef NAZARA_COMPILER_MSVC
// Disable warning: unary minus operator applied to unsigned type, result still unsigned
#pragma warning(push)
#pragma warning(disable: 4146)
#endif
constexpr UInt32 byteCount = 256;
constexpr UInt32 iterationCount = 8;
std::array<UInt32, byteCount> crc32Table{};
for (UInt32 byte = 0u; byte < byteCount; ++byte)
{
UInt32 crc = byte;
for (UInt32 i = 0; i < iterationCount; ++i)
{
UInt32 mask = static_cast<UInt32>(-(crc & 1));
crc = (crc >> 1) ^ (polynomial & mask);
}
crc32Table[byte] = crc;
}
return crc32Table;
#ifdef NAZARA_COMPILER_MSVC
#pragma warning(pop)
#endif
}
// Stores CRC-32 table and softly validates it.
static constexpr auto crc32Table = GenerateCRC32Table();
static_assert(
crc32Table.size() == 256 &&
crc32Table[1] == 0x77073096 &&
crc32Table[255] == 0x2D02EF8D,
"gen_crc32_table generated unexpected result."
);
}
/*!
* \ingroup core
* \brief Access a non-typed struct field by offset
* \return A pointer to the field of the asked type
*
* \param basePtr Pointer to the start of the struct
* \param offset Offset to the field (as generated by offsetof or similar)
*/
template<typename T>
decltype(auto) AccessByOffset(void* basePtr, std::size_t offset)
{
if constexpr (std::is_lvalue_reference_v<T>)
return *reinterpret_cast<std::remove_reference_t<T>*>(static_cast<UInt8*>(basePtr) + offset);
else if constexpr (std::is_pointer_v<T>)
return reinterpret_cast<T>(static_cast<UInt8*>(basePtr) + offset);
else
static_assert(AlwaysFalse<T>(), "AccessByOffset requires a reference or pointer type");
}
/*!
* \ingroup core
* \brief Access a non-typed struct field by offset
* \return A pointer to the field of the asked type
*
* \param basePtr Pointer to the start of the struct
* \param offset Offset to the field (as generated by offsetof or similar)
*/
template<typename T>
decltype(auto) AccessByOffset(const void* basePtr, std::size_t offset)
{
static_assert(std::is_lvalue_reference_v<T> || std::is_pointer_v<T>);
if constexpr (std::is_lvalue_reference_v<T>)
return *reinterpret_cast<std::remove_reference_t<T>*>(static_cast<const UInt8*>(basePtr) + offset);
else if constexpr (std::is_pointer_v<T>)
return reinterpret_cast<T>(static_cast<const UInt8*>(basePtr) + offset);
else
static_assert(AlwaysFalse<T>(), "AccessByOffset requires a reference or pointer type");
}
/*!
* \ingroup core
* \brief Align an offset
* \return Aligned offset according to alignment
*
* \param offset Base offset
* \param alignment Non-zero alignment
*
* \see AlignPow2
*/
template<typename T>
constexpr T Align(T offset, T alignment)
{
assert(alignment > 0);
return ((offset + alignment - 1) / alignment) * alignment;
}
/*!
* \ingroup core
* \brief Align an offset
* \return Aligned offset according to a power of two alignment
*
* \param offset Base offset
* \param alignment Non-zero power of two alignment
*
* \see Align
* \remark This function is quicker than Align but only works with power of two alignment values
*/
template<typename T>
constexpr T AlignPow2(T offset, T alignment)
{
assert(alignment > 0);
assert(IsPowerOfTwo(alignment));
return (offset + alignment - 1) & ~(alignment - 1);
}
/*!
* \ingroup core
* \brief Applies the tuple to the function (e.g. calls the function using the tuple content as arguments)
* \return The result of the function
*
* \param fn Function
* \param t Tuple of arguments for the function
*
* \see Apply
*/
template<typename F, typename Tuple>
decltype(auto) Apply(F&& fn, Tuple&& t)
{
constexpr std::size_t tSize = std::tuple_size<typename std::remove_reference<Tuple>::type>::value;
return Detail::ApplyImplFunc(std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
}
/*!
* \ingroup core
* \brief Applies the tuple to the member function on an object (e.g. calls the member function using the tuple content as arguments)
* \return The result of the member function called
*
* \param object Object of a class
* \param fn Member function
* \param t Tuple of arguments for the member function
*
* \see Apply
*/
template<typename O, typename F, typename Tuple>
decltype(auto) Apply(O& object, F&& fn, Tuple&& t)
{
constexpr std::size_t tSize = std::tuple_size<typename std::remove_reference<Tuple>::type>::value;
return Detail::ApplyImplMethod(object, std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
}
/*!
* \ingroup core
* \brief Returns the number of bits occupied by the type T
* \return Number of bits occupied by the type
*/
template<typename T>
constexpr std::size_t BitCount()
{
return CHAR_BIT * sizeof(T);
}
/*!
* \ingroup core
* \brief Computes the hash of a hashable object
@ -249,279 +58,12 @@ namespace Nz
return hash.End();
}
// From https://stackoverflow.com/questions/28675727/using-crc32-algorithm-to-hash-string-at-compile-time
constexpr UInt32 CRC32(const UInt8* input, std::size_t size) noexcept
{
UInt32 crc = 0xFFFFFFFFu;
for (std::size_t i = 0u; i < size; ++i)
crc = Detail::crc32Table[(crc ^ input[i]) & 0xFF] ^ (crc >> 8);
return ~crc;
}
constexpr UInt32 CRC32(const char* str) noexcept
{
UInt32 crc = 0xFFFFFFFFu;
for (std::size_t i = 0u; str[i]; ++i)
crc = Detail::crc32Table[(crc ^ str[i]) & 0xFF] ^ (crc >> 8);
return ~crc;
}
constexpr UInt32 CRC32(const std::string_view& str) noexcept
{
UInt32 crc = 0xFFFFFFFFu;
for (std::size_t i = 0u; i < str.size(); ++i)
crc = Detail::crc32Table[(crc ^ str[i]) & 0xFF] ^ (crc >> 8);
return ~crc;
}
template<std::size_t N>
constexpr UInt32 CRC32(const char (&str)[N]) noexcept
{
UInt32 crc = 0xFFFFFFFFu;
for (std::size_t i = 0u; i < N - 1; ++i)
crc = Detail::crc32Table[(crc ^ str[i]) & 0xFF] ^ (crc >> 8);
return ~crc;
}
/*!
* \ingroup core
* \brief Returns the number of elements in a C-array
* \return The number of elements
*
* \see CountOf
*/
template<typename T, std::size_t N>
constexpr std::size_t CountOf(T(&)[N]) noexcept
{
return N;
}
/*!
* \ingroup core
* \brief Returns the number of elements in a container
* \return The number of elements
*
* \param c Container with the member function "size()"
*
* \see CountOf
*/
template<typename T>
std::size_t CountOf(const T& c)
{
return c.size();
}
inline bool HashAppend(AbstractHash& hash, const std::string_view& v)
{
hash.Append(reinterpret_cast<const UInt8*>(v.data()), v.size());
return true;
}
/*!
* \ingroup core
* \brief Combines two hash in one
*
* \param seed First value that will be modified (expected to be 64bits)
* \param v Second value to hash
*/
// Algorithm from CityHash by Google
// http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co
template<typename T>
void HashCombine(std::size_t& seed, const T& v)
{
const UInt64 kMul = 0x9ddfea08eb382d69ULL;
std::hash<T> hasher;
UInt64 a = (hasher(v) ^ seed) * kMul;
a ^= (a >> 47);
UInt64 b = (seed ^ a) * kMul;
b ^= (b >> 47);
seed = static_cast<std::size_t>(b * kMul);
}
/*!
* \ingroup core
* \brief Check if a value is a power of two
* \return true if value is a power of two
*
* \param value Non-zero value
*/
template<typename T>
bool IsPowerOfTwo(T value)
{
assert(value != 0);
return (value & (value - 1)) == 0;
}
/*!
* \ingroup core
* \brief Helper function to retrieve a key in a map which has to exist
* \return Value associated with key
*
* \param map Map
* \param key Key, has to exist in map
*/
template<typename K, typename V>
V& Retrieve(std::unordered_map<K, V>& map, const K& key)
{
auto it = map.find(key);
assert(it != map.end());
return it->second;
}
/*!
* \ingroup core
* \brief Helper function to retrieve a key in a map which has to exist
* \return Value associated with key
*
* \param map Map
* \param key Key, has to exist in map
*/
template<typename K, typename V>
const V& Retrieve(const std::unordered_map<K, V>& map, const K& key)
{
auto it = map.find(key);
assert(it != map.end());
return it->second;
}
/*!
* \ingroup core
* \brief Reverse the bit order of the integer
* \return integer with reversed bits
*
* \param integer Integer whose bits are to be reversed
*/
template<typename T>
T ReverseBits(T integer)
{
T reversed = 0;
for (std::size_t i = 0; i < sizeof(T); ++i)
reversed |= T(Detail::BitReverseTable256[(integer >> i * 8) & 0xFF]) << (sizeof(T) * 8 - (i + 1) * 8);
return reversed;
}
template<typename To, typename From>
To SafeCast(From&& value)
{
#ifdef NAZARA_COMPILER_MSVC
// Disable unreachable code warnings
#pragma warning(push)
#pragma warning(disable: 4702)
#endif
#if defined(NAZARA_DEBUG) && !defined(NDEBUG)
if constexpr (std::is_integral_v<To>)
{
if constexpr (std::is_enum_v<From>)
{
return SafeCast<To>(static_cast<std::underlying_type_t<From>>(value));
}
else if constexpr (std::is_floating_point_v<From>)
{
assert(std::floor(value) == value);
assert(value <= static_cast<From>(std::numeric_limits<To>::max()));
assert(value >= static_cast<From>(std::numeric_limits<To>::lowest()));
}
else if constexpr (std::is_integral_v<From>)
{
// Type capable of storing the biggest value between the two types
using MaxValueType = std::conditional_t<(sizeof(From) > sizeof(To) || (sizeof(From) == sizeof(To) && std::is_signed_v<To>)), From, To>;
// Type capable of storing the smallest value between the two types
using MinValueType = std::conditional_t<(sizeof(From) > sizeof(To) || (sizeof(From) == sizeof(To) && std::is_signed_v<From>)), From, To>;
if constexpr (!std::is_signed_v<To>)
assert(value >= 0);
assert(static_cast<MaxValueType>(value) <= static_cast<MaxValueType>(std::numeric_limits<To>::max()));
assert(static_cast<MinValueType>(value) >= static_cast<MinValueType>(std::numeric_limits<To>::lowest()));
}
}
else if constexpr (std::is_enum_v<To>)
{
return static_cast<To>(SafeCast<std::underlying_type_t<To>>(value));
}
else if constexpr (std::is_floating_point_v<To>)
{
if constexpr (std::is_floating_point_v<From>)
{
// Type capable of storing the biggest value between the two types
using MaxValueType = std::conditional_t<(sizeof(From) > sizeof(To)), From, To>;
// Type capable of storing the smallest value between the two types
using MinValueType = std::conditional_t<(sizeof(From) > sizeof(To)), From, To>;
assert(static_cast<MaxValueType>(value) <= static_cast<MaxValueType>(std::numeric_limits<To>::max()));
assert(static_cast<MinValueType>(value) >= static_cast<MinValueType>(std::numeric_limits<To>::lowest()));
}
}
else if constexpr (std::is_reference_v<To>)
{
if constexpr (std::is_reference_v<From>)
{
using BaseFromType = std::remove_reference_t<std::remove_cv_t<From>>;
using BaseToType = std::remove_reference_t<std::remove_cv_t<To>>;
if constexpr (!std::is_same_v<BaseFromType, BaseToType> && std::is_base_of_v<From, To> && std::is_polymorphic_v<From>)
{
using ToPtr = std::add_pointer_t<std::remove_reference_t<To>>;
assert(dynamic_cast<ToPtr>(&value) != nullptr);
}
}
}
else if constexpr (std::is_pointer_v<To>)
{
if constexpr (std::is_pointer_v<From>)
{
using BaseFromType = std::remove_pointer_t<std::remove_cv_t<From>>;
using BaseToType = std::remove_pointer_t<std::remove_cv_t<To>>;
if constexpr (!std::is_same_v<BaseFromType, BaseToType> && std::is_base_of_v<From, To> && std::is_polymorphic_v<From>)
{
assert(dynamic_cast<To>(value) != nullptr);
}
}
}
#endif
return static_cast<To>(value);
#ifdef NAZARA_COMPILER_MSVC
#pragma warning(pop)
#endif
}
template<typename T, typename U>
std::unique_ptr<T> StaticUniquePointerCast(std::unique_ptr<U>&& ptr)
{
return std::unique_ptr<T>(SafeCast<T*>(ptr.release()));
}
template<typename T>
constexpr auto UnderlyingCast(T value) -> std::underlying_type_t<T>
{
return static_cast<std::underlying_type_t<T>>(value);
}
template<typename T> struct PointedType<T*> { using type = T; };
template<typename T> struct PointedType<T* const> { using type = T; };
template<typename T> struct PointedType<T* volatile> { using type = T; };
template<typename T> struct PointedType<T* const volatile> { using type = T; };
template<typename T>
bool Serialize(SerializationContext& context, T&& value)
{

View File

@ -1,208 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_BITSET_HPP
#define NAZARA_CORE_BITSET_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <limits>
#include <memory>
#include <string>
#include <type_traits>
namespace Nz
{
class AbstractHash;
template<typename Block = UInt32, class Allocator = std::allocator<Block>>
class Bitset
{
static_assert(std::is_integral<Block>::value && std::is_unsigned<Block>::value, "Block must be a unsigned integral type");
public:
class Bit;
using PointerSequence = std::pair<const void*, std::size_t>; //< Start pointer, bit offset
Bitset();
explicit Bitset(std::size_t bitCount, bool val);
explicit Bitset(const char* bits);
Bitset(const char* bits, std::size_t bitCount);
Bitset(const Bitset& bitset) = default;
explicit Bitset(const std::string_view& bits);
explicit Bitset(const std::string& bits);
template<typename T> Bitset(T value);
Bitset(Bitset&& bitset) noexcept = default;
~Bitset() noexcept = default;
template<typename T> void AppendBits(T bits, std::size_t bitCount);
void Clear() noexcept;
std::size_t Count() const;
void Flip();
std::size_t FindFirst() const;
std::size_t FindNext(std::size_t bit) const;
Block GetBlock(std::size_t i) const;
std::size_t GetBlockCount() const;
std::size_t GetCapacity() const;
std::size_t GetSize() const;
void PerformsAND(const Bitset& a, const Bitset& b);
void PerformsNOT(const Bitset& a);
void PerformsOR(const Bitset& a, const Bitset& b);
void PerformsXOR(const Bitset& a, const Bitset& b);
bool Intersects(const Bitset& bitset) const;
void Reserve(std::size_t bitCount);
void Resize(std::size_t bitCount, bool defaultVal = false);
void Reset();
void Reset(std::size_t bit);
void Reverse();
void Set(bool val = true);
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) noexcept;
bool Test(std::size_t bit) const;
bool TestAll() const;
bool TestAny() const;
bool TestNone() const;
template<typename T> T To() const;
std::string ToString() const;
void UnboundedReset(std::size_t bit);
void UnboundedSet(std::size_t bit, bool val = true);
bool UnboundedTest(std::size_t bit) const;
PointerSequence Write(const void* ptr, std::size_t bitCount);
PointerSequence Write(const PointerSequence& sequence, std::size_t bitCount);
Bit operator[](std::size_t index);
bool operator[](std::size_t index) const;
Bitset operator~() const;
Bitset& operator=(const Bitset& bitset) = default;
Bitset& operator=(const std::string_view& bits);
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);
static constexpr Block fullBitMask = std::numeric_limits<Block>::max();
static constexpr std::size_t bitsPerBlock = BitCount<Block>();
static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
static Bitset FromPointer(const void* ptr, std::size_t bitCount, PointerSequence* sequence = nullptr);
private:
std::size_t FindFirstFrom(std::size_t blockIndex) const;
Block GetLastBlockMask() const;
void ResetExtraBits();
static std::size_t ComputeBlockCount(std::size_t bitCount);
static std::size_t GetBitIndex(std::size_t bit);
static std::size_t GetBlockIndex(std::size_t bit);
std::vector<Block, Allocator> m_blocks;
std::size_t m_bitCount;
};
template<typename Block, class Allocator>
class Bitset<Block, Allocator>::Bit
{
friend Bitset<Block, Allocator>;
public:
Bit(const Bit& bit) = default;
Bit& Flip();
Bit& Reset();
Bit& Set(bool val = true);
bool Test() const;
template<bool BadCall = true>
void* operator&() const;
explicit operator bool() const;
Bit& operator=(bool val);
Bit& operator=(const Bit& bit);
Bit& operator|=(bool val);
Bit& operator&=(bool val);
Bit& operator^=(bool val);
Bit& operator-=(bool val);
private:
Bit(Block& block, Block mask) :
m_block(block),
m_mask(mask)
{
}
Block& m_block;
Block m_mask;
};
template<typename Block, class Allocator>
std::ostream& operator<<(std::ostream& out, const Bitset<Block, Allocator>& bitset);
template<typename Block, class Allocator>
bool operator==(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
bool operator!=(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
bool operator<(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
bool operator<=(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
bool operator>(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
bool operator>=(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
Bitset<Block, Allocator> operator&(const Bitset<Block, Allocator>& lhs, const Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
Bitset<Block, Allocator> operator|(const Bitset<Block, Allocator>& lhs, const Bitset<Block, Allocator>& rhs);
template<typename Block, class Allocator>
Bitset<Block, Allocator> operator^(const Bitset<Block, Allocator>& lhs, const Bitset<Block, Allocator>& rhs);
}
namespace std
{
template<typename Block, class Allocator>
void swap(Nz::Bitset<Block, Allocator>& lhs, Nz::Bitset<Block, Allocator>& rhs) noexcept;
}
#include <Nazara/Core/Bitset.inl>
#endif // NAZARA_CORE_BITSET_HPP

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,8 @@
#define NAZARA_CORE_BYTESTREAM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/SerializationContext.hpp>
#include <memory>

View File

@ -1,41 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_CALLONEXIT_HPP
#define NAZARA_CORE_CALLONEXIT_HPP
#include <Nazara/Prerequisites.hpp>
#include <optional>
namespace Nz
{
template<typename F>
class CallOnExit
{
public:
CallOnExit() = default;
CallOnExit(F&& functor);
CallOnExit(const CallOnExit&) = delete;
CallOnExit(CallOnExit&&) noexcept = delete;
~CallOnExit();
void CallAndReset();
void Reset();
CallOnExit& operator=(const CallOnExit&) = delete;
CallOnExit& operator=(CallOnExit&&) noexcept = default;
private:
std::optional<F> m_functor;
};
template<typename F>
CallOnExit(F) -> CallOnExit<F>;
}
#include <Nazara/Core/CallOnExit.inl>
#endif // NAZARA_CORE_CALLONEXIT_HPP

View File

@ -1,64 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::CallOnExit
* \brief Core class that represents a function to call at the end of the scope
*/
/*!
* \brief Constructs a CallOnExit object with a functor
*
* \param func Function to call on exit
*/
template<typename F>
CallOnExit<F>::CallOnExit(F&& functor) :
m_functor(std::move(functor))
{
}
/*!
* \brief Destructs the object and calls the function
*/
template<typename F>
CallOnExit<F>::~CallOnExit()
{
if (m_functor)
(*m_functor)();
}
/*!
* \brief Calls the function and sets the new callback
*
* \param func Function to call on exit
*/
template<typename F>
void CallOnExit<F>::CallAndReset()
{
if (m_functor)
(*m_functor)();
m_functor.reset();
}
/*!
* \brief Resets the function
*
* \param func Function to call on exit
*/
template<typename F>
void CallOnExit<F>::Reset()
{
m_functor.reset();
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_CLOCK_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
namespace Nz
{

View File

@ -61,9 +61,6 @@
// 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 NT 6.0 (and greater) (Breaks the compatibility with Windows XP)
#define NAZARA_CORE_WINDOWS_NT6 1
/*
// Sets the time between waking thread timers and activating a timer (in milliseconds)

View File

@ -10,7 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ModuleBase.hpp>
#include <Nazara/Core/Modules.hpp>
#include <Nazara/Core/TypeList.hpp>
#include <Nazara/Utils/TypeList.hpp>
namespace Nz
{

View File

@ -8,7 +8,8 @@
#define NAZARA_CORE_DYNLIB_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
#include <filesystem>
#if defined(NAZARA_PLATFORM_WINDOWS)

View File

@ -1,37 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_ENDIANNESS_HPP
#define NAZARA_CORE_ENDIANNESS_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Enums.hpp>
#if !defined(NAZARA_BIG_ENDIAN) && !defined(NAZARA_LITTLE_ENDIAN)
// Automatic detection following macros of compiler
#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__)
#define NAZARA_BIG_ENDIAN
#elif defined(__i386__) || defined(__i386) || defined(__X86__) || defined (__x86_64) || defined(_M_I86) || \
defined(_M_IX86) || defined(_M_X64)
#define NAZARA_LITTLE_ENDIAN
#else
#error Failed to identify endianness, you must define either NAZARA_BIG_ENDIAN or NAZARA_LITTLE_ENDIAN
#endif
#elif defined(NAZARA_BIG_ENDIAN) && defined(NAZARA_LITTLE_ENDIAN)
#error You cannot define both NAZARA_BIG_ENDIAN and NAZARA_LITTLE_ENDIAN
#endif
namespace Nz
{
inline constexpr Endianness GetPlatformEndianness();
inline void SwapBytes(void* buffer, std::size_t size);
template<typename T> T SwapBytes(T value);
}
#include <Nazara/Core/Endianness.inl>
#endif // NAZARA_CORE_ENDIANNESS_HPP

View File

@ -1,52 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/Endianness.hpp>
#include <algorithm>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \brief Gets the platform endianness
* \return Type of the endianness
*/
inline constexpr Endianness GetPlatformEndianness()
{
#if defined(NAZARA_BIG_ENDIAN)
return Endianness::BigEndian;
#elif defined(NAZARA_LITTLE_ENDIAN)
return Endianness::LittleEndian;
#endif
}
/*!
* \ingroup core
* \brief Swaps the byte for endianness operations
*
* \param buffer Raw memory
* \param size Size to change endianness
*
* \remark If size is greater than the preallocated buffer, the behavior is undefined
*/
inline void SwapBytes(void* buffer, std::size_t size)
{
UInt8* bytes = static_cast<UInt8*>(buffer);
std::size_t i = 0;
std::size_t j = size - 1;
while (i < j)
std::swap(bytes[i++], bytes[j--]);
}
template<typename T>
T SwapBytes(T value)
{
SwapBytes(&value, sizeof(T));
return value;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -7,7 +7,7 @@
#ifndef NAZARA_CORE_ENUMS_HPP
#define NAZARA_CORE_ENUMS_HPP
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Utils/Flags.hpp>
namespace Nz
{
@ -28,16 +28,6 @@ namespace Nz
Max = AtEnd
};
enum class Endianness
{
Unknown = -1,
BigEndian,
LittleEndian,
Max = LittleEndian
};
enum class ErrorMode
{
None,

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_ERRORFLAGS_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
namespace Nz

View File

@ -9,9 +9,9 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Utils/Endianness.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
#include <ctime>
#include <filesystem>
#include <fstream>

View File

@ -1,104 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_FLAGS_HPP
#define NAZARA_CORE_FLAGS_HPP
#include <Nazara/Prerequisites.hpp>
#include <type_traits>
namespace Nz
{
// From: https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
template<typename E>
struct EnumAsFlags
{
};
template<typename, typename = void>
struct IsEnumFlag : std::false_type {};
template<typename T>
struct IsEnumFlag<T, std::void_t<decltype(EnumAsFlags<T>::max)>> : std::true_type {};
template<typename, typename = void>
struct GetEnumAutoFlag : std::bool_constant<true> {};
template<typename T>
struct GetEnumAutoFlag<T, std::void_t<decltype(T::AutoFlag)>> : std::bool_constant<T::AutoFlag> {};
template<typename E>
class Flags
{
static_assert(std::is_enum_v<E>, "Type must be an enumeration");
static_assert(IsEnumFlag<E>(), "Enum has not been enabled as flags by an EnumAsFlags specialization");
static_assert(std::is_same_v<std::remove_cv_t<decltype(EnumAsFlags<E>::max)>, E>, "EnumAsFlags field max should be of the same type as the enum");
static constexpr std::size_t MaxValue = static_cast<std::size_t>(EnumAsFlags<E>::max);
static constexpr bool AutoFlag = GetEnumAutoFlag<E>();
using BitField16 = std::conditional_t<(MaxValue >= 8), UInt16, UInt8>;
using BitField32 = std::conditional_t<(MaxValue >= 16), UInt32, BitField16>;
public:
using BitField = std::conditional_t<(MaxValue >= 32), UInt64, BitField32>;
constexpr Flags(BitField value = 0);
constexpr Flags(E enumVal);
void Clear();
void Clear(const Flags& flags);
void Set(const Flags& flags);
constexpr bool Test(const Flags& flags) const;
explicit constexpr operator bool() const;
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value && sizeof(T) >= sizeof(BitField)>> explicit constexpr operator T() const;
constexpr Flags operator~() const;
constexpr Flags operator&(const Flags& rhs) const;
constexpr Flags operator|(const Flags& rhs) const;
constexpr Flags operator^(const Flags& rhs) const;
constexpr bool operator==(const Flags& rhs) const;
constexpr bool operator!=(const Flags& rhs) const;
/*constexpr*/ Flags& operator|=(const Flags& rhs);
/*constexpr*/ Flags& operator&=(const Flags& rhs);
/*constexpr*/ Flags& operator^=(const Flags& rhs);
static constexpr BitField GetFlagValue(E enumValue);
static constexpr BitField ValueMask = BitField((UInt64(1) << (MaxValue + 1)) - 1);
private:
BitField m_value;
};
template<typename E> constexpr Flags<E> operator&(E lhs, Flags<E> rhs);
template<typename E> constexpr Flags<E> operator|(E lhs, Flags<E> rhs);
template<typename E> constexpr Flags<E> operator^(E lhs, Flags<E> rhs);
// Little hack to have them in both Nz and global scope
namespace FlagsOperators
{
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator~(E lhs);
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator&(E lhs, E rhs);
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator|(E lhs, E rhs);
template<typename E> constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator^(E lhs, E rhs);
}
using namespace FlagsOperators;
}
using namespace Nz::FlagsOperators;
#include <Nazara/Core/Flags.inl>
#endif // NAZARA_CORE_FLAGS_HPP

View File

@ -1,394 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/Flags.hpp>
#include <functional>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::Flags
* \brief Core class used to combine enumeration values into flags bitfield
*/
/*!
* \brief Constructs a Flags object using a bitfield
*
* \param value Bitfield to be used
*
* Uses a bitfield to builds the flag value. (e.g. if bit 0 is active, then Enum value 0 will be set as active).
*/
template<typename E>
constexpr Flags<E>::Flags(BitField value) :
m_value(value)
{
}
/*!
* \brief Constructs a Flags object using an Enum value
*
* \param enumVal enumVal
*
* Setup a Flags object with only one flag active (corresponding to the enum value passed as argument).
*/
template<typename E>
constexpr Flags<E>::Flags(E enumVal) :
Flags(GetFlagValue(enumVal))
{
}
/*!
* \brief Clear all flags
*
* \see Test
*/
template<typename E>
void Flags<E>::Clear()
{
m_value = 0;
}
/*!
* \brief Clear some flags
*
* \param flags Flags to be cleared
*
* \see Test
*/
template<typename E>
void Flags<E>::Clear(const Flags& flags)
{
m_value &= ~flags.m_value;
}
/*!
* \brief Enable some flags
*
* \param flags Flags to be enabled
*
* \see Clear
* \see Test
*/
template<typename E>
void Flags<E>::Set(const Flags& flags)
{
m_value |= flags.m_value;
}
/*!
* \brief Tests if all flags from a Flags object are enabled
* \return True if all tested flags are enabled.
*
* \see Clear
*/
template<typename E>
constexpr bool Flags<E>::Test(const Flags& flags) const
{
return (m_value & flags.m_value) == flags.m_value;
}
/*!
* \brief Tests any flag
* \return True if any flag is enabled.
*
* This will convert to a boolean value allowing to check if any flag is set.
*/
template<typename E>
constexpr Flags<E>::operator bool() const
{
return m_value != 0;
}
/*!
* \brief Converts to an integer
* \return Enabled flags as a integer
*
* This will only works if the integer type is large enough to store all flags states
*/
template<typename E>
template<typename T, typename>
constexpr Flags<E>::operator T() const
{
return m_value;
}
/*!
* \brief Reverse flag states
* \return Opposite enabled flags
*
* This will returns a copy of the Flags object with reversed flags states.
*/
template<typename E>
constexpr Flags<E> Flags<E>::operator~() const
{
return Flags((~m_value) & ValueMask);
}
/*!
* \brief Compare flag states
* \return Shared flags
*
* \param rhs Flags to compare with.
*
* This will returns a copy of the Flags object with only enabled flags in common with the parameter
*/
template<typename E>
constexpr Flags<E> Flags<E>::operator&(const Flags& rhs) const
{
return Flags(m_value & rhs.m_value);
}
/*!
* \brief Combine flag states
* \return Combined flags
*
* This will returns a copy of the Flags object with combined flags from the parameter.
*
* \param rhs Flags to combine with.
*/
template<typename E>
constexpr Flags<E> Flags<E>::operator|(const Flags& rhs) const
{
return Flags(m_value | rhs.m_value);
}
/*!
* \brief XOR flag states
* \return XORed flags.
*
* \param rhs Flags to XOR with.
*
* This performs a XOR (Exclusive OR) on a copy of the flag object.
* This will returns a copy of the object with disabled common flags and enabled unique ones.
*/
template<typename E>
constexpr Flags<E> Flags<E>::operator^(const Flags& rhs) const
{
return Flags((m_value ^ rhs.m_value) & ValueMask);
}
/*!
* \brief Check equality with flag object
* \return True if both flags objects have the same states.
*
* \param rhs Flags to compare with.
*
* Compare two Flags object and returns true if the flag states are identical.
*/
template<typename E>
constexpr bool Flags<E>::operator==(const Flags& rhs) const
{
return m_value == rhs.m_value;
}
/*!
* \brief Check inequality with flag object
* \return True if both flags objects have different states.
*
* \param rhs Flags to compare with.
*
* Compare two Flags object and returns true if the flag states are identical.
*/
template<typename E>
constexpr bool Flags<E>::operator!=(const Flags& rhs) const
{
return !operator==(rhs);
}
/*!
* \brief Combine flag states
* \return A reference to the object.
*
* \param rhs Flags to combine with.
*
* This will enable flags which are enabled in parameter object and not in Flag object.
*/
template<typename E>
/*constexpr*/ Flags<E>& Flags<E>::operator|=(const Flags& rhs)
{
m_value |= rhs.m_value;
return *this;
}
/*!
* \brief Compare flag states
* \return A reference to the object.
*
* \param rhs Flags to compare with.
*
* This will disable flags which are disabled in parameter object and enabled in Flag object (and vice-versa).
*/
template<typename E>
/*constexpr*/ Flags<E>& Flags<E>::operator&=(const Flags& rhs)
{
m_value &= rhs.m_value;
return *this;
}
/*!
* \brief XOR flag states
* \return A reference to the object.
*
* \param rhs Flags to XOR with.
*
* This performs a XOR (Exclusive OR) on the flag object.
* This will disable flags enabled in both Flags objects and enable those enabled in only one of the Flags objects.
*/
template<typename E>
/*constexpr*/ Flags<E>& Flags<E>::operator^=(const Flags& rhs)
{
m_value ^= rhs.m_value;
m_value &= ValueMask;
return *this;
}
/*!
* \brief Returns a bitfield corresponding to an enum value.
* \return Bitfield representation of the enum value
*
* \param enumValue Enumeration value to get as a bitfield.
*
* Internally, every enum option is turned into a bit, this function allows to get a bitfield with only the bit of the enumeration value enabled.
*/
template<typename E>
constexpr typename Flags<E>::BitField Flags<E>::GetFlagValue(E enumValue)
{
if constexpr (AutoFlag)
return 1U << static_cast<BitField>(enumValue);
else
return enumValue;
}
/*!
* \brief Compare flag states
* \return Compared flags
*
* This will returns a copy of the Flags object compared with the enum state.
*
* \param lhs Enum to compare with flags.
* \param rhs Flags object.
*/
template<typename E>
constexpr Flags<E> operator&(E lhs, Flags<E> rhs)
{
return rhs & lhs;
}
/*!
* \brief Combine flag states
* \return Combined flags
*
* This will returns a copy of the Flags object combined with the enum state.
*
* \param lhs Enum to combine with flags.
* \param rhs Flags object.
*/
template<typename E>
constexpr Flags<E> operator|(E lhs, Flags<E> rhs)
{
return rhs | lhs;
}
/*!
* \brief XOR flag states
* \return XORed flags
*
* This will returns a copy of the Flags object XORed with the enum state.
*
* \param lhs Enum to XOR with flags.
* \param rhs Flags object.
*/
template<typename E>
constexpr Flags<E> operator^(E lhs, Flags<E> rhs)
{
return rhs ^ lhs;
}
namespace FlagsOperators
{
/*!
* \brief Override binary NOT operator on enum to turns into a Flags object.
* \return A Flags object with reversed bits.
*
* \param lhs Enumeration value to reverse.
*
* Returns a Flags object with all state enabled except for the enum one.
*/
template<typename E>
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator~(E lhs)
{
return ~Flags<E>(lhs);
}
/*!
* \brief Override binary AND operator on enum to turns into a Flags object.
* \return A Flags object with compare enum states.
*
* \param lhs First enumeration value to compare.
* \param rhs Second enumeration value to compare.
*
* Returns a Flags object with compared states from the two enumeration values.
* In this case, only one flag will be enabled if both enumeration values are the same.
*/
template<typename E>
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator&(E lhs, E rhs)
{
return Flags<E>(lhs) & rhs;
}
/*!
* \brief Override binary OR operator on enum to turns into a Flags object.
* \return A Flags object with combined enum states.
*
* \param lhs First enumeration value to combine.
* \param rhs Second enumeration value to combine.
*
* Returns a Flags object with combined states from the two enumeration values.
*/
template<typename E>
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator|(E lhs, E rhs)
{
return Flags<E>(lhs) | rhs;
}
/*!
* \brief Override binary XOR operator on enum to turns into a Flags object.
* \return A Flags object with XORed enum states.
*
* \param lhs First enumeration value to compare.
* \param rhs Second enumeration value to compare.
*
* Returns a Flags object with XORed states from the two enumeration values.
* In this case, two flags will be enabled if both the enumeration values are different.
*/
template<typename E>
constexpr std::enable_if_t<IsEnumFlag<E>::value, Flags<E>> operator^(E lhs, E rhs)
{
return Flags<E>(lhs) ^ rhs;
}
}
}
namespace std
{
template<typename E>
struct hash<Nz::Flags<E>>
{
std::size_t operator()(const Nz::Flags<E>& flags)
{
using UnderlyingType = typename Nz::Flags<E>::BitField;
using Hasher = hash<UnderlyingType>;
Hasher hasher;
return hasher(static_cast<UnderlyingType>(flags));
}
};
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -7,8 +7,10 @@
#ifndef NAZARA_CORE_HANDLEDOBJECT_HPP
#define NAZARA_CORE_HANDLEDOBJECT_HPP
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utils/Bitset.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <memory>
#include <vector>

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_HARDWAREINFO_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <string>

View File

@ -8,7 +8,10 @@
#define NAZARA_CORE_LOG_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <string>
#ifdef NAZARA_DEBUG

View File

@ -1,44 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_MEMORYHELPER_HPP
#define NAZARA_CORE_MEMORYHELPER_HPP
#if defined(NAZARA_COMPILER_MSVC) || defined(NAZARA_COMPILER_MINGW)
#include <malloc.h>
// with MSVC, using alloca with a size of zero returns a valid pointer
#define NAZARA_ALLOCA(size) _alloca(size)
#define NAZARA_ALLOCA_SUPPORT
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
#include <alloca.h>
// with Clang/GCC, using alloca with a size of zero does nothing good
#define NAZARA_ALLOCA(size) alloca(((size) > 0) ? (size) : 1)
#define NAZARA_ALLOCA_SUPPORT
#endif
#include <cstddef>
namespace Nz
{
void OperatorDelete(void* ptr);
void* OperatorNew(std::size_t size);
template<typename T, typename... Args>
T* PlacementNew(T* ptr, Args&&... args);
template<typename T>
void PlacementDestroy(T* ptr);
}
#include <Nazara/Core/MemoryHelper.inl>
#endif // NAZARA_CORE_MEMORYHELPER_HPP

View File

@ -1,87 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// I'm not proud of those five following lines but ti's hard to do with another way now
#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#else
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MemoryManager.hpp>
#include <cassert>
#include <new>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \fn Nz::MemoryHelper
* \brief Core functions that helps the handle of memory in the engine
*/
/*!
* \brief Calls the operator delete on the pointer
*
* \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator delete
*/
inline void OperatorDelete(void* ptr)
{
#if NAZARA_CORE_MANAGE_MEMORY
MemoryManager::Free(ptr);
#else
operator delete(ptr);
#endif
}
/*!
* \brief Calls the operator new on the pointer
*
* \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator new
*/
inline void* OperatorNew(std::size_t size)
{
#if NAZARA_CORE_MANAGE_MEMORY
return MemoryManager::Allocate(size);
#else
return operator new(size);
#endif
}
/*!
* \brief Constructs the object inplace
* \return Pointer to the constructed object
*
* \param ptr Pointer to raw memory allocated
* \param args Arguments for the constructor
*/
template<typename T, typename... Args>
T* PlacementNew(T* ptr, Args&&... args)
{
return new (ptr) T(std::forward<Args>(args)...);
}
/*!
* \brief Calls the object destructor explicitly
*
* \param ptr Pointer to a previously constructed pointer on raw memory
*
* \remark This does not deallocate memory, and is a no-op on a null pointer
*/
template<typename T>
void PlacementDestroy(T* ptr)
{
if (ptr)
ptr->~T();
}
}
#include <Nazara/Core/DebugOff.hpp>
// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine)
#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_MEMORYMANAGER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <cstddef>
namespace Nz

View File

@ -1,113 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_MEMORYPOOL_HPP
#define NAZARA_CORE_MEMORYPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <iterator>
#include <memory>
#include <vector>
namespace Nz
{
template<typename T, std::size_t Alignment = alignof(T)>
class MemoryPool
{
public:
class iterator;
friend iterator;
MemoryPool(std::size_t blockSize);
MemoryPool(const MemoryPool&) = delete;
MemoryPool(MemoryPool&&) noexcept = default;
~MemoryPool();
template<typename... Args> T* Allocate(std::size_t& index, Args&&... args);
void Clear();
void Free(std::size_t index);
std::size_t GetAllocatedEntryCount() const;
std::size_t GetBlockCount() const;
std::size_t GetBlockSize() const;
std::size_t GetFreeEntryCount() const;
void Reset();
T* RetrieveFromIndex(std::size_t index);
std::size_t RetrieveEntryIndex(const T* data);
// std interface
iterator begin();
iterator end();
std::size_t size();
MemoryPool& operator=(const MemoryPool&) = delete;
MemoryPool& operator=(MemoryPool&& pool) noexcept = default;
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
private:
void AllocateBlock();
T* GetAllocatedPointer(std::size_t blockIndex, std::size_t localIndex);
std::pair<std::size_t, std::size_t> GetFirstAllocatedEntry() const;
std::pair<std::size_t, std::size_t> GetFirstAllocatedEntryFromBlock(std::size_t blockIndex) const;
std::pair<std::size_t, std::size_t> GetNextAllocatedEntry(std::size_t blockIndex, std::size_t localIndex) const;
using AlignedStorage = std::aligned_storage_t<sizeof(T), Alignment>;
struct Block
{
std::size_t occupiedEntryCount = 0;
std::unique_ptr<AlignedStorage[]> memory;
Bitset<UInt64> freeEntries;
Bitset<UInt64> occupiedEntries; //< Opposite of freeEntries
};
std::size_t m_blockSize;
std::vector<Block> m_blocks;
};
template<typename T, std::size_t Alignment>
class MemoryPool<T, Alignment>::iterator
{
friend MemoryPool;
public:
using iterator_category = std::input_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = T&;
iterator(const iterator&) = default;
iterator(iterator&&) = default;
iterator& operator=(const iterator&) = default;
iterator& operator=(iterator&&) = default;
iterator operator++(int);
iterator& operator++();
bool operator==(const iterator& rhs) const;
bool operator!=(const iterator& rhs) const;
reference operator*() const;
private:
iterator(MemoryPool* owner, std::size_t blockIndex, std::size_t localIndex);
std::size_t m_blockIndex;
std::size_t m_localIndex;
MemoryPool* m_owner;
};
}
#include <Nazara/Core/MemoryPool.inl>
#endif // NAZARA_CORE_MEMORYPOOL_HPP

View File

@ -1,384 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/MemoryPool.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/MemoryHelper.hpp>
#include <stdexcept>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::MemoryPool
* \brief Core class that represents a memory pool
*/
/*!
* \brief Constructs a MemoryPool object
*
* \param blockSize Size of blocks that will be allocated
*/
template<typename T, std::size_t Alignment>
MemoryPool<T, Alignment>::MemoryPool(std::size_t blockSize) :
m_blockSize(blockSize)
{
// Allocate one block by default
AllocateBlock();
}
/*!
* \brief Destroy the memory pool, calling the destructor for every allocated object and desallocating blocks
*/
template<typename T, std::size_t Alignment>
MemoryPool<T, Alignment>::~MemoryPool()
{
Reset();
}
/*!
* \brief Allocates enough memory for the size and returns a pointer to it
* \return A pointer to memory allocated
*
* \param index Output entry index (which can be used for deallocation)
*
* \remark If the size is greater than the blockSize of pool, new operator is called
*/
template<typename T, std::size_t Alignment>
template<typename... Args>
T* MemoryPool<T, Alignment>::Allocate(std::size_t& index, Args&&... args)
{
std::size_t blockIndex = 0;
std::size_t localIndex = InvalidIndex;
for (; blockIndex < m_blocks.size(); ++blockIndex)
{
auto& block = m_blocks[blockIndex];
if (block.occupiedEntryCount == m_blockSize)
continue;
localIndex = block.freeEntries.FindFirst();
assert(localIndex != block.freeEntries.npos);
break;
}
if (blockIndex >= m_blocks.size())
{
// No more room, allocate a new block
blockIndex = m_blocks.size();
localIndex = 0;
AllocateBlock();
}
assert(localIndex != InvalidIndex);
auto& block = m_blocks[blockIndex];
block.freeEntries.Reset(localIndex);
block.occupiedEntries.Set(localIndex);
block.occupiedEntryCount++;
T* entry = reinterpret_cast<T*>(&block.memory[localIndex]);
PlacementNew(entry, std::forward<Args>(args)...);
index = blockIndex * m_blockSize + localIndex;
return entry;
}
/*!
* \brief Clears the memory pool
*
* This is call the destructor of every active entry and invalidate every entry index, and will free every allocated block
*
* \see Reset
*/
template<typename T, std::size_t Alignment>
void MemoryPool<T, Alignment>::Clear()
{
Reset();
m_blocks.clear();
}
/*!
* \brief Returns an object memory to the memory pool
*
* Calls the destructor of the target object and returns its memory to the pool
*
* \param index Index of the allocated object
*
* \see Reset
*/
template<typename T, std::size_t Alignment>
void MemoryPool<T, Alignment>::Free(std::size_t index)
{
std::size_t blockIndex = index / m_blockSize;
std::size_t localIndex = index % m_blockSize;
T* entry = GetAllocatedPointer(blockIndex, localIndex);
PlacementDestroy(entry);
auto& block = m_blocks[blockIndex];
assert(block.occupiedEntryCount > 0);
block.occupiedEntryCount--;
block.freeEntries.Set(localIndex);
block.occupiedEntries.Reset(localIndex);
}
/*!
* \brief Returns the number of allocated entries
* \return How many entries are currently allocated
*/
template<typename T, std::size_t Alignment>
std::size_t MemoryPool<T, Alignment>::GetAllocatedEntryCount() const
{
std::size_t count = 0;
for (auto& block : m_blocks)
count += block.occupiedEntryCount;
return count;
}
/*!
* \brief Gets the block count
* \return How many block are currently allocated for this memory pool
*/
template<typename T, std::size_t Alignment>
std::size_t MemoryPool<T, Alignment>::GetBlockCount() const
{
return m_blocks.size();
}
/*!
* \brief Gets the block size
* \return Size of each block (i.e. how many items can fit in a block)
*/
template<typename T, std::size_t Alignment>
std::size_t MemoryPool<T, Alignment>::GetBlockSize() const
{
return m_blockSize;
}
/*!
* \brief Returns the number of free entries
* \return How many entries are currently freed
*/
template<typename T, std::size_t Alignment>
std::size_t MemoryPool<T, Alignment>::GetFreeEntryCount() const
{
std::size_t count = m_blocks.size() * m_blockSize;
return count - GetAllocatedEntryCount();
}
/*!
* \brief Resets the memory pool
*
* This is call the destructor of every active entry and invalidate every entry index, returning the pool to full capacity
* Note that memory is not freed
*
* \see Clear
*/
template<typename T, std::size_t Alignment>
void MemoryPool<T, Alignment>::Reset()
{
for (std::size_t blockIndex = 0; blockIndex < m_blocks.size(); ++blockIndex)
{
auto& block = m_blocks[blockIndex];
if (block.occupiedEntryCount == 0)
continue;
for (std::size_t localIndex = block.occupiedEntries.FindFirst(); localIndex != block.occupiedEntries.npos; localIndex = block.occupiedEntries.FindNext(localIndex))
{
T* entry = reinterpret_cast<T*>(&m_blocks[blockIndex].memory[localIndex]);
PlacementDestroy(entry);
}
block.freeEntries.Reset(true);
block.occupiedEntries.Reset(false);
block.occupiedEntryCount = 0;
}
}
/*!
* \brief Retrieve an allocated pointer based on a valid entry index
*
* \param index Entry index
*
* \return Pointer to the allocated entry
*
* \remark index must be valid
*/
template<typename T, std::size_t Alignment>
T* MemoryPool<T, Alignment>::RetrieveFromIndex(std::size_t index)
{
std::size_t blockIndex = index / m_blockSize;
std::size_t localIndex = index % m_blockSize;
return GetAllocatedPointer(blockIndex, localIndex);
}
/*!
* \brief Retrieve an entry index based on an allocated pointer
*
* \param data Allocated entry pointed
*
* \return Corresponding index, or InvalidIndex if it's not part of this pool
*/
template<typename T, std::size_t Alignment>
std::size_t MemoryPool<T, Alignment>::RetrieveEntryIndex(const T* data)
{
std::size_t blockIndex = 0;
std::size_t localIndex = InvalidIndex;
for (; blockIndex < m_blocks.size(); ++blockIndex)
{
auto& block = m_blocks[blockIndex];
const T* startPtr = reinterpret_cast<const T*>(&block.memory[0]);
if (data >= startPtr && data < startPtr + m_blockSize)
{
// Part of block
localIndex = SafeCast<std::size_t>(data - startPtr);
assert(data == reinterpret_cast<const T*>(&block.memory[localIndex]));
break;
}
}
if (blockIndex == m_blocks.size())
return InvalidIndex;
assert(localIndex != InvalidIndex);
return blockIndex * m_blockSize + localIndex;
}
template<typename T, std::size_t Alignment>
auto MemoryPool<T, Alignment>::begin() -> iterator
{
auto [blockIndex, localIndex] = GetFirstAllocatedEntry();
return iterator(this, blockIndex, localIndex);
}
template<typename T, std::size_t Alignment>
auto MemoryPool<T, Alignment>::end() -> iterator
{
return iterator(this, InvalidIndex, InvalidIndex);
}
template<typename T, std::size_t Alignment>
std::size_t MemoryPool<T, Alignment>::size()
{
return GetAllocatedEntryCount();
}
template<typename T, std::size_t Alignment>
void MemoryPool<T, Alignment>::AllocateBlock()
{
auto& block = m_blocks.emplace_back();
block.freeEntries.Resize(m_blockSize, true);
block.occupiedEntries.Resize(m_blockSize, false);
block.memory = std::make_unique<AlignedStorage[]>(m_blockSize);
}
template<typename T, std::size_t Alignment>
T* MemoryPool<T, Alignment>::GetAllocatedPointer(std::size_t blockIndex, std::size_t localIndex)
{
assert(blockIndex < m_blocks.size());
auto& block = m_blocks[blockIndex];
assert(block.occupiedEntries.Test(localIndex));
return reinterpret_cast<T*>(&block.memory[localIndex]);
}
template<typename T, std::size_t Alignment>
std::pair<std::size_t, std::size_t> MemoryPool<T, Alignment>::GetFirstAllocatedEntry() const
{
return GetFirstAllocatedEntryFromBlock(0);
}
template<typename T, std::size_t Alignment>
std::pair<std::size_t, std::size_t> MemoryPool<T, Alignment>::GetFirstAllocatedEntryFromBlock(std::size_t blockIndex) const
{
// Search in next block
std::size_t localIndex = InvalidIndex;
for (; blockIndex < m_blocks.size(); ++blockIndex)
{
auto& block = m_blocks[blockIndex];
if (block.occupiedEntryCount == 0)
continue;
localIndex = block.occupiedEntries.FindFirst();
assert(localIndex != block.occupiedEntries.npos);
break;
}
if (blockIndex >= m_blocks.size())
return { InvalidIndex, InvalidIndex };
return { blockIndex, localIndex };
}
template<typename T, std::size_t Alignment>
std::pair<std::size_t, std::size_t> MemoryPool<T, Alignment>::GetNextAllocatedEntry(std::size_t blockIndex, std::size_t localIndex) const
{
assert(blockIndex < m_blocks.size());
auto& block = m_blocks[blockIndex];
std::size_t nextLocalIndex = block.occupiedEntries.FindNext(localIndex);
if (nextLocalIndex != block.occupiedEntries.npos)
return { blockIndex, nextLocalIndex };
// Search in next block
return GetFirstAllocatedEntryFromBlock(blockIndex + 1);
}
template<typename T, std::size_t Alignment>
MemoryPool<T, Alignment>::iterator::iterator(MemoryPool* owner, std::size_t blockIndex, std::size_t localIndex) :
m_blockIndex(blockIndex),
m_localIndex(localIndex),
m_owner(owner)
{
}
template<typename T, std::size_t Alignment>
auto MemoryPool<T, Alignment>::iterator::operator++(int) -> iterator
{
iterator copy(*this);
operator++();
return copy;
}
template<typename T, std::size_t Alignment>
auto MemoryPool<T, Alignment>::iterator::operator++() -> iterator&
{
auto [blockIndex, localIndex] = m_owner->GetNextAllocatedEntry(m_blockIndex, m_localIndex);
m_blockIndex = blockIndex;
m_localIndex = localIndex;
return *this;
}
template<typename T, std::size_t Alignment>
bool MemoryPool<T, Alignment>::iterator::operator==(const iterator& rhs) const
{
assert(m_owner == rhs.m_owner);
return m_blockIndex == rhs.m_blockIndex && m_localIndex == rhs.m_localIndex;
}
template<typename T, std::size_t Alignment>
bool MemoryPool<T, Alignment>::iterator::operator!=(const iterator& rhs) const
{
return !operator==(rhs);
}
template<typename T, std::size_t Alignment>
auto MemoryPool<T, Alignment>::iterator::operator*() const -> reference
{
return *m_owner->GetAllocatedPointer(m_blockIndex, m_localIndex);
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -8,8 +8,8 @@
#define NAZARA_CORE_MEMORYSTREAM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
namespace Nz
{

View File

@ -19,7 +19,7 @@ namespace Nz
ModuleBase<T>::ModuleBase(std::string moduleName, T* pointer, NoLog) :
m_moduleName(std::move(moduleName))
{
NazaraAssert(T::s_instance == nullptr, "only one instance of " + m_moduleName + " must exist at a given time");
NazaraAssert(T::s_instance == nullptr, "only one instance of " + m_moduleName + " can exist at a given time");
T::s_instance = pointer;
}

View File

@ -7,7 +7,7 @@
#ifndef NAZARA_CORE_MODULES_HPP
#define NAZARA_CORE_MODULES_HPP
#include <Nazara/Core/TypeList.hpp>
#include <Nazara/Utils/TypeList.hpp>
namespace Nz
{

View File

@ -1,38 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_MOVABLEPTR_HPP
#define NAZARA_CORE_MOVABLEPTR_HPP
namespace Nz
{
template<typename T>
class MovablePtr
{
public:
MovablePtr(T* value = nullptr);
MovablePtr(const MovablePtr&) = default;
MovablePtr(MovablePtr&& ptr) noexcept;
~MovablePtr() = default;
T* Get() const;
T* operator->() const;
operator T*() const;
MovablePtr& operator=(T* value);
MovablePtr& operator=(const MovablePtr&) = default;
MovablePtr& operator=(MovablePtr&& ptr) noexcept;
private:
T* m_value;
};
}
#include <Nazara/Core/MovablePtr.inl>
#endif // NAZARA_CORE_MOVABLEPTR_HPP

View File

@ -1,64 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/MovablePtr.hpp>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::MovablePtr
* \brief Wraps a raw (non-proprietary) to allows it to be moved implicitly
*/
template<typename T>
MovablePtr<T>::MovablePtr(T* value) :
m_value(value)
{
}
template<typename T>
MovablePtr<T>::MovablePtr(MovablePtr&& ptr) noexcept :
m_value(ptr.m_value)
{
ptr.m_value = nullptr;
}
template<typename T>
inline T* MovablePtr<T>::Get() const
{
return m_value;
}
template<typename T>
T* MovablePtr<T>::operator->() const
{
return m_value;
}
template<typename T>
MovablePtr<T>::operator T*() const
{
return m_value;
}
template<typename T>
inline MovablePtr<T>& MovablePtr<T>::operator=(T* value)
{
m_value = value;
return *this;
}
template<typename T>
MovablePtr<T>& MovablePtr<T>::operator=(MovablePtr&& ptr) noexcept
{
std::swap(m_value, ptr.m_value);
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -1,38 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_MOVABLEVALUE_HPP
#define NAZARA_CORE_MOVABLEVALUE_HPP
namespace Nz
{
template<typename T>
class MovableValue
{
public:
MovableValue(T value = T{});
MovableValue(const MovableValue&) = default;
MovableValue(MovableValue&& ptr) noexcept;
~MovableValue() = default;
T& Get();
const T& Get() const;
operator T&();
operator const T&() const;
MovableValue& operator=(T value);
MovableValue& operator=(const MovableValue&) = default;
MovableValue& operator=(MovableValue&& ptr) noexcept;
private:
T m_value;
};
}
#include <Nazara/Core/MovableValue.inl>
#endif // NAZARA_CORE_MOVABLEVALUE_HPP

View File

@ -1,64 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/MovableValue.hpp>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
template<typename T>
MovableValue<T>::MovableValue(T value) :
m_value(std::move(value))
{
}
template<typename T>
MovableValue<T>::MovableValue(MovableValue&& val) noexcept :
m_value()
{
std::swap(m_value, val.m_value);
}
template<typename T>
T& MovableValue<T>::Get()
{
return m_value;
}
template<typename T>
const T& MovableValue<T>::Get() const
{
return m_value;
}
template<typename T>
MovableValue<T>::operator T&()
{
return m_value;
}
template<typename T>
MovableValue<T>::operator const T&() const
{
return m_value;
}
template<typename T>
MovableValue<T>& MovableValue<T>::operator=(T value)
{
m_value = std::move(value);
return *this;
}
template<typename T>
MovableValue<T>& MovableValue<T>::operator=(MovableValue&& ptr) noexcept
{
std::swap(m_value, ptr.m_value);
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -1,30 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_OFFSETOF_HPP
#define NAZARA_CORE_OFFSETOF_HPP
// By "Jesse Good" from SO:
// http://stackoverflow.com/questions/12811330/c-compile-time-offsetof-inside-a-template?answertab=votes#tab-top
namespace Nz
{
namespace Detail
{
template <typename T, typename M> T GetClassType(M T::*);
template <typename T, typename M> M GetMemberType(M T::*);
template <typename T, typename R, R T::*M>
constexpr std::size_t OffsetOf()
{
return reinterpret_cast<std::size_t>(&((static_cast<T*>(0))->*M));
}
}
}
#define NazaraOffsetOf(type, member) Nz::Detail::OffsetOf<decltype(Nz::Detail::GetClassType(&type::member)), decltype(Nz::Detail::GetMemberType(&type::member)), &type::member>()
#endif // NAZARA_CORE_OFFSETOF_HPP

View File

@ -9,7 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
#include <atomic>
#include <string>
#include <unordered_map>

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_PLUGINMANAGER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <filesystem>
#include <set>

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_REFCOUNTED_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <atomic>
namespace Nz

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_RESOURCE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <filesystem>
namespace Nz

View File

@ -9,9 +9,9 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Utils/Endianness.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
#include <Nazara/Utils/TypeTag.hpp>
namespace Nz
{

View File

@ -1,139 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_SIGNAL_HPP
#define NAZARA_CORE_SIGNAL_HPP
#include <functional>
#include <memory>
#include <vector>
#define NazaraDetailSignal(Keyword, SignalName, ...) using SignalName ## Type = Nz::Signal<__VA_ARGS__>; \
Keyword SignalName ## Type SignalName
#define NazaraSignal(SignalName, ...) NazaraDetailSignal(mutable, SignalName, __VA_ARGS__)
#define NazaraStaticSignal(SignalName, ...) NazaraDetailSignal(static, SignalName, __VA_ARGS__)
#define NazaraStaticSignalImpl(Class, SignalName) Class :: SignalName ## Type Class :: SignalName
#define NazaraSlotType(Class, SignalName) Class::SignalName ## Type::ConnectionGuard
#define NazaraSlot(Class, SignalName, SlotName) NazaraSlotType(Class, SignalName) SlotName
namespace Nz
{
template<typename... Args>
class Signal
{
public:
using Callback = std::function<void(Args...)>;
class Connection;
class ConnectionGuard;
Signal();
Signal(const Signal&);
Signal(Signal&& signal) noexcept;
~Signal() = default;
void Clear();
Connection Connect(const Callback& func);
Connection Connect(Callback&& func);
template<typename O> Connection Connect(O& object, void (O::*method)(Args...));
template<typename O> Connection Connect(O* object, void (O::*method)(Args...));
template<typename O> Connection Connect(const O& object, void (O::*method)(Args...) const);
template<typename O> Connection Connect(const O* object, void (O::*method)(Args...) const);
void operator()(Args... args) const;
Signal& operator=(const Signal&);
Signal& operator=(Signal&& signal) noexcept;
private:
struct Slot;
using SlotPtr = std::shared_ptr<Slot>;
using SlotList = std::vector<SlotPtr>;
using SlotListIndex = typename SlotList::size_type;
struct Slot
{
Slot(Signal* me) :
signal(me)
{
}
Callback callback;
Signal* signal;
SlotListIndex index;
};
void Disconnect(const SlotPtr& slot) noexcept;
SlotList m_slots;
mutable SlotListIndex m_slotIterator;
};
template<typename... Args>
class Signal<Args...>::Connection
{
using BaseClass = Signal<Args...>;
friend BaseClass;
public:
Connection() = default;
Connection(const Connection& connection) = default;
Connection(Connection&& connection) noexcept;
~Connection() = default;
template<typename... ConnectArgs>
void Connect(BaseClass& signal, ConnectArgs&&... args);
void Disconnect() noexcept;
bool IsConnected() const;
Connection& operator=(const Connection& connection) = default;
Connection& operator=(Connection&& connection) noexcept;
private:
Connection(const SlotPtr& slot);
std::weak_ptr<Slot> m_ptr;
};
template<typename... Args>
class Signal<Args...>::ConnectionGuard
{
using BaseClass = Signal<Args...>;
using Connection = typename BaseClass::Connection;
public:
ConnectionGuard() = default;
ConnectionGuard(const Connection& connection);
ConnectionGuard(const ConnectionGuard& connection) = delete;
ConnectionGuard(Connection&& connection);
ConnectionGuard(ConnectionGuard&& connection) noexcept = default;
~ConnectionGuard();
template<typename... ConnectArgs>
void Connect(BaseClass& signal, ConnectArgs&&... args);
void Disconnect() noexcept;
Connection& GetConnection();
bool IsConnected() const;
ConnectionGuard& operator=(const Connection& connection);
ConnectionGuard& operator=(const ConnectionGuard& connection) = delete;
ConnectionGuard& operator=(Connection&& connection);
ConnectionGuard& operator=(ConnectionGuard&& connection) noexcept;
private:
Connection m_connection;
};
}
#include <Nazara/Core/Signal.inl>
#endif // NAZARA_CORE_SIGNAL_HPP

View File

@ -1,485 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/Signal.hpp>
#include <Nazara/Core/Error.hpp>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::Signal
* \brief Core class that represents a signal, a list of objects waiting for its message
*/
/*!
* \brief Constructs a Signal object by default
*/
template<typename... Args>
Signal<Args...>::Signal() :
m_slotIterator(0)
{
}
/*!
* \brief Constructs a Signal object by default
*
* \remark It doesn't make sense to copy a signal, this is only available for convenience to allow compiler-generated copy constructors
*/
template<typename ...Args>
Signal<Args...>::Signal(const Signal&) :
Signal()
{
}
/*!
* \brief Constructs a Signal object by move semantic
*
* \param signal Signal to move in this
*/
template<typename... Args>
Signal<Args...>::Signal(Signal&& signal) noexcept
{
operator=(std::move(signal));
}
/*!
* \brief Clears the list of actions attached to the signal
*/
template<typename... Args>
void Signal<Args...>::Clear()
{
m_slots.clear();
m_slotIterator = 0;
}
/*!
* \brief Connects a function to the signal
* \return Connection attached to the signal
*
* \param func Non-member function
*/
template<typename... Args>
typename Signal<Args...>::Connection Signal<Args...>::Connect(const Callback& func)
{
return Connect(Callback(func));
}
/*!
* \brief Connects a function to the signal
* \return Connection attached to the signal
*
* \param func Non-member function
*/
template<typename... Args>
typename Signal<Args...>::Connection Signal<Args...>::Connect(Callback&& func)
{
NazaraAssert(func, "Invalid function");
// Since we're incrementing the slot vector size, we need to replace our iterator at the end
// (Except when we are iterating on the signal)
bool resetIt = (m_slotIterator >= m_slots.size());
auto tempPtr = std::make_shared<Slot>(this);
tempPtr->callback = std::move(func);
tempPtr->index = m_slots.size();
m_slots.emplace_back(std::move(tempPtr));
if (resetIt)
m_slotIterator = m_slots.size(); //< Replace the iterator to the end
return Connection(m_slots.back());
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(O& object, void (O::*method) (Args...))
{
return Connect([&object, method] (Args&&... args)
{
return (object .* method) (std::forward<Args>(args)...);
});
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(O* object, void (O::*method)(Args...))
{
return Connect([object, method] (Args&&... args)
{
return (object ->* method) (std::forward<Args>(args)...);
});
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(const O& object, void (O::*method) (Args...) const)
{
return Connect([&object, method] (Args&&... args)
{
return (object .* method) (std::forward<Args>(args)...);
});
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(const O* object, void (O::*method)(Args...) const)
{
return Connect([object, method] (Args&&... args)
{
return (object ->* method) (std::forward<Args>(args)...);
});
}
/*!
* \brief Applies the list of arguments to every callback functions
*
* \param args Arguments to send with the message
*/
template<typename... Args>
void Signal<Args...>::operator()(Args... args) const
{
for (m_slotIterator = 0; m_slotIterator < m_slots.size(); ++m_slotIterator)
m_slots[m_slotIterator]->callback(args...);
}
/*!
* \brief Doesn't do anything
* \return A reference to this
*
* \remark This is only for convenience to allow compiled-generated assignation operator
*/
template<typename... Args>
Signal<Args...>& Signal<Args...>::operator=(const Signal&)
{
return *this;
}
/*!
* \brief Moves the signal into this
* \return A reference to this
*
* \param signal Signal to move in this
*/
template<typename... Args>
Signal<Args...>& Signal<Args...>::operator=(Signal&& signal) noexcept
{
m_slots = std::move(signal.m_slots);
m_slotIterator = signal.m_slotIterator;
// We need to update the signal pointer inside of each slot
for (SlotPtr& slot : m_slots)
slot->signal = this;
return *this;
}
/*!
* \brief Disconnects a listener from this signal
*
* \param slot Pointer to the ith listener of the signal
*
* \remark Produces a NazaraAssert if slot is invalid (nullptr)
* \remark Produces a NazaraAssert if index of slot is invalid
* \remark Produces a NazaraAssert if slot is not attached to this signal
*/
template<typename... Args>
void Signal<Args...>::Disconnect(const SlotPtr& slot) noexcept
{
NazaraAssert(slot, "Invalid slot pointer");
NazaraAssert(slot->index < m_slots.size(), "Invalid slot index");
NazaraAssert(slot->signal == this, "Slot is not attached to this signal");
// "Swap this slot with the last one and pop" idiom
// This will preserve slot indexes
// Can we safely "remove" this slot?
if (m_slotIterator >= (m_slots.size() - 1) || slot->index > m_slotIterator)
{
// Yes we can
SlotPtr& newSlot = m_slots[slot->index];
newSlot = std::move(m_slots.back());
newSlot->index = slot->index; //< Update the moved slot index before resizing (in case it's the last one)
}
else
{
// Nope, let's be tricky
SlotPtr& current = m_slots[m_slotIterator];
SlotPtr& newSlot = m_slots[slot->index];
newSlot = std::move(current);
newSlot->index = slot->index; //< Update the moved slot index
current = std::move(m_slots.back());
current->index = m_slotIterator; //< Update the moved slot index
--m_slotIterator;
}
// Pop the last entry (from where we moved our slot)
m_slots.pop_back();
}
/*!
* \class Nz::Signal::Connection
* \brief Core class that represents a connection attached to a signal
*/
/*!
* \brief Constructs a Signal::Connection object with by move semantic
*
* \param connection Connection object to move
*/
template<typename... Args>
Signal<Args...>::Connection::Connection(Connection&& connection) noexcept :
m_ptr(std::move(connection.m_ptr))
{
connection.m_ptr.reset(); //< Fuck you GCC 4.9
}
/*!
* \brief Constructs a Signal::Connection object with a slot
*
* \param slot Slot of the listener
*/
template<typename... Args>
Signal<Args...>::Connection::Connection(const SlotPtr& slot) :
m_ptr(slot)
{
}
/*!
* \brief Connects to a signal with arguments
*
* \param signal New signal to listen
* \param args Arguments for the signal
*/
template<typename... Args>
template<typename... ConnectArgs>
void Signal<Args...>::Connection::Connect(BaseClass& signal, ConnectArgs&&... args)
{
operator=(signal.Connect(std::forward<ConnectArgs>(args)...));
}
/*!
* \brief Disconnects the connection from the signal
*/
template<typename... Args>
void Signal<Args...>::Connection::Disconnect() noexcept
{
if (SlotPtr ptr = m_ptr.lock())
ptr->signal->Disconnect(ptr);
}
/*!
* \brief Checks whether the connection is still active with the signal
* \return true if signal is still active
*/
template<typename... Args>
bool Signal<Args...>::Connection::IsConnected() const
{
return !m_ptr.expired();
}
/*!
* \brief Constructs a Signal::ConnectionGuard object by move semantic
*
* \param connection Connection to move
*/
template<typename... Args>
typename Signal<Args...>::Connection& Signal<Args...>::Connection::operator=(Connection&& connection) noexcept
{
m_ptr = std::move(connection.m_ptr);
connection.m_ptr.reset(); //< Fuck you GCC 4.9
return *this;
}
/*!
* \class Nz::Signal::ConnectionGuard
* \brief Core class that represents a RAII for a connection attached to a signal
*/
/*!
* \brief Constructs a Signal::ConnectionGuard object with a connection
*
* \param connection Connection for the scope
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::ConnectionGuard(const Connection& connection) :
m_connection(connection)
{
}
/*!
* \brief Constructs a Signal::ConnectionGuard object with a connection by move semantic
*
* \param connection Connection for the scope
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::ConnectionGuard(Connection&& connection) :
m_connection(std::move(connection))
{
}
/*!
* \brief Destructs the object and disconnects the connection
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::~ConnectionGuard()
{
m_connection.Disconnect();
}
/*!
* \brief Connects to a signal with arguments
*
* \param signal New signal to listen
* \param args Arguments for the signal
*/
template<typename... Args>
template<typename... ConnectArgs>
void Signal<Args...>::ConnectionGuard::Connect(BaseClass& signal, ConnectArgs&&... args)
{
m_connection.Disconnect();
m_connection.Connect(signal, std::forward<ConnectArgs>(args)...);
}
/*!
* \brief Disconnects the connection from the signal
*/
template<typename... Args>
void Signal<Args...>::ConnectionGuard::Disconnect() noexcept
{
m_connection.Disconnect();
}
/*!
* \brief Gets the connection attached to the signal
* \return Connection of the signal
*/
template<typename... Args>
typename Signal<Args...>::Connection& Signal<Args...>::ConnectionGuard::GetConnection()
{
return m_connection;
}
/*!
* \brief Checks whether the connection is still active with the signal
* \return true if signal is still active
*/
template<typename... Args>
bool Signal<Args...>::ConnectionGuard::IsConnected() const
{
return m_connection.IsConnected();
}
/*!
* \brief Assigns the connection into this
* \return A reference to this
*
* \param connection Connection to assign into this
*/
template<typename... Args>
typename Signal<Args...>::ConnectionGuard& Signal<Args...>::ConnectionGuard::operator=(const Connection& connection)
{
m_connection.Disconnect();
m_connection = connection;
return *this;
}
/*!
* \brief Moves the Connection into this
* \return A reference to this
*
* \param connection Connection to move in this
*/
template<typename... Args>
typename Signal<Args...>::ConnectionGuard& Signal<Args...>::ConnectionGuard::operator=(Connection&& connection)
{
if (&connection != this)
{
m_connection.Disconnect();
m_connection = std::move(connection);
}
return *this;
}
/*!
* \brief Moves the ConnectionGuard into this
* \return A reference to this
*
* \param connection ConnectionGuard to move in this
*/
template<typename... Args>
typename Signal<Args...>::ConnectionGuard& Signal<Args...>::ConnectionGuard::operator=(ConnectionGuard&& connection) noexcept
{
if (&connection != this)
{
m_connection.Disconnect();
m_connection = std::move(connection.m_connection);
}
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -1,81 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_SPARSEPTR_HPP
#define NAZARA_CORE_SPARSEPTR_HPP
///FIXME: Is SparsePtr a really good name for this class ?
#include <Nazara/Prerequisites.hpp>
#include <cstddef>
#include <type_traits>
namespace Nz
{
template<typename T>
class SparsePtr
{
public:
using BytePtr = std::conditional_t<std::is_const<T>::value, const UInt8*, UInt8*>;
using VoidPtr = std::conditional_t<std::is_const<T>::value, const void*, void*>;
SparsePtr();
SparsePtr(T* ptr);
SparsePtr(VoidPtr ptr, int stride);
SparsePtr(VoidPtr ptr, std::size_t stride);
template<typename U> SparsePtr(const SparsePtr<U>& ptr);
SparsePtr(const SparsePtr& ptr) = default;
~SparsePtr() = default;
VoidPtr GetPtr() const;
int GetStride() const;
void Reset();
void Reset(T* ptr);
void Reset(VoidPtr ptr, int stride);
void Reset(const SparsePtr& ptr);
template<typename U> void Reset(const SparsePtr<U>& ptr);
void SetPtr(VoidPtr ptr);
void SetStride(int stride);
explicit operator bool() const;
explicit operator T*() const;
T& operator*() const;
T* operator->() const;
template<typename U> T& operator[](U index) const;
SparsePtr& operator=(const SparsePtr& ptr) = default;
template<typename U> SparsePtr operator+(U count) const;
template<typename U> SparsePtr operator-(U count) const;
std::ptrdiff_t operator-(const SparsePtr& ptr) const;
template<typename U> SparsePtr& operator+=(U count);
template<typename U> SparsePtr& operator-=(U count);
SparsePtr& operator++();
SparsePtr operator++(int);
SparsePtr& operator--();
SparsePtr operator--(int);
bool operator==(const SparsePtr& ptr) const;
bool operator!=(const SparsePtr& ptr) const;
bool operator<(const SparsePtr& ptr) const;
bool operator>(const SparsePtr& ptr) const;
bool operator<=(const SparsePtr& ptr) const;
bool operator>=(const SparsePtr& ptr) const;
private:
BytePtr m_ptr;
int m_stride;
};
}
#include <Nazara/Core/SparsePtr.inl>
#endif // NAZARA_CORE_SPARSEPTR_HPP

View File

@ -1,483 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/SparsePtr.hpp>
#include <cassert>
#include <iterator>
#include <limits>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::SparsePtr
* \brief Core class that represents a pointer and the step between two elements
*/
/*!
* \brief Constructs a SparsePtr object by default
*/
template<typename T>
SparsePtr<T>::SparsePtr()
{
Reset();
}
/*!
* \brief Constructs a SparsePtr object with a pointer
*
* \param ptr Pointer to data
*/
template<typename T>
SparsePtr<T>::SparsePtr(T* ptr)
{
Reset(ptr);
}
/*!
* \brief Constructs a SparsePtr object with a pointer and a step
*
* \param ptr Pointer to data
* \param stride Step between two elements
*/
template<typename T>
SparsePtr<T>::SparsePtr(VoidPtr ptr, int stride)
{
Reset(ptr, stride);
}
/*!
* \brief Constructs a SparsePtr object with a pointer and a step
*
* \param ptr Pointer to data
* \param stride Step between two elements
*
* \remark This constructor only exists because std::size_t is a frequent type for constructing this object, but stride may not be higher than int max
*/
template<typename T>
SparsePtr<T>::SparsePtr(VoidPtr ptr, std::size_t stride)
{
assert(stride <= static_cast<unsigned int>(std::numeric_limits<int>::max()));
Reset(ptr, static_cast<int>(stride));
}
/*!
* \brief Constructs a SparsePtr object from another type of SparsePtr
*
* \param ptr Pointer to data of type U to convert to type T
*/
template<typename T>
template<typename U>
SparsePtr<T>::SparsePtr(const SparsePtr<U>& ptr)
{
Reset(ptr);
}
/*!
* \brief Gets the original pointer
* \return Pointer to the first data
*/
template<typename T>
typename SparsePtr<T>::VoidPtr SparsePtr<T>::GetPtr() const
{
return m_ptr;
}
/*!
* \brief Gets the stride
* \return Step between two elements
*/
template<typename T>
int SparsePtr<T>::GetStride() const
{
return m_stride;
}
/*!
* \brief Resets the SparsePtr
*/
template<typename T>
void SparsePtr<T>::Reset()
{
SetPtr(nullptr);
SetStride(0);
}
/*!
* \brief Resets the SparsePtr with a pointer
*
* \param ptr Pointer to data
*
* \remark stride is set to sizeof(T)
*/
template<typename T>
void SparsePtr<T>::Reset(T* ptr)
{
SetPtr(ptr);
SetStride(sizeof(T));
}
/*!
* \brief Resets the SparsePtr with a pointer and its stride
*
* \param ptr Pointer to data
* \param stride Step between two elements
*/
template<typename T>
void SparsePtr<T>::Reset(VoidPtr ptr, int stride)
{
SetPtr(ptr);
SetStride(stride);
}
/*!
* \brief Resets the SparsePtr with another SparsePtr
*
* \param ptr Another sparsePtr
*/
template<typename T>
void SparsePtr<T>::Reset(const SparsePtr& ptr)
{
SetPtr(ptr.GetPtr());
SetStride(ptr.GetStride());
}
/*!
* \brief Resets the SparsePtr with another type of SparsePtr
*
* \param ptr Another sparsePtr
*/
template<typename T>
template<typename U>
void SparsePtr<T>::Reset(const SparsePtr<U>& ptr)
{
static_assert(std::is_convertible<U*, T*>::value, "Source type pointer cannot be implicitly converted to target type pointer");
SetPtr(static_cast<T*>(ptr.GetPtr()));
SetStride(ptr.GetStride());
}
/*!
* \brief Sets the pointer
*
* \param ptr Pointer to data
*/
template<typename T>
void SparsePtr<T>::SetPtr(VoidPtr ptr)
{
m_ptr = static_cast<BytePtr>(ptr);
}
/*!
* \brief Sets the stride
*
* \param stride Step between two elements
*/
template<typename T>
void SparsePtr<T>::SetStride(int stride)
{
m_stride = stride;
}
/*!
* \brief Converts the pointer to bool
* \return true if pointer is not nullptr
*/
template<typename T>
SparsePtr<T>::operator bool() const
{
return m_ptr != nullptr;
}
/*!
* \brief Converts the pointer to a pointer to the value
* \return The value of the pointer
*/
template<typename T>
SparsePtr<T>::operator T*() const
{
return reinterpret_cast<T*>(m_ptr);
}
/*!
* \brief Dereferences the pointer
* \return The dereferencing of the pointer
*/
template<typename T>
T& SparsePtr<T>::operator*() const
{
return *reinterpret_cast<T*>(m_ptr);
}
/*!
* \brief Dereferences the pointer
* \return The dereferencing of the pointer
*/
template<typename T>
T* SparsePtr<T>::operator->() const
{
return reinterpret_cast<T*>(m_ptr);
}
/*!
* \brief Gets the ith element of the stride pointer
* \return A reference to the ith value
*
* \param index Number of stride to do
*/
template<typename T>
template<typename U>
T& SparsePtr<T>::operator[](U index) const
{
static_assert(std::is_integral_v<U>, "index must be an integral type");
return *reinterpret_cast<T*>(m_ptr + index * m_stride);
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A SparsePtr with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
template<typename U>
SparsePtr<T> SparsePtr<T>::operator+(U count) const
{
static_assert(std::is_integral_v<U>, "count must be an integral type");
return SparsePtr(m_ptr + count * m_stride, m_stride);
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A SparsePtr with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
template<typename U>
SparsePtr<T> SparsePtr<T>::operator-(U count) const
{
static_assert(std::is_integral_v<U>, "count must be an integral type");
return SparsePtr(m_ptr - count * m_stride, m_stride);
}
/*!
* \brief Gets the difference between the two SparsePtr
* \return The difference of elements: ptr - this->ptr
*
* \param ptr Other ptr
*/
template<typename T>
std::ptrdiff_t SparsePtr<T>::operator-(const SparsePtr& ptr) const
{
return (m_ptr - ptr.m_ptr) / m_stride;
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A reference to this pointer with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
template<typename U>
SparsePtr<T>& SparsePtr<T>::operator+=(U count)
{
static_assert(std::is_integral_v<U>, "count must be an integral type");
m_ptr += count * m_stride;
return *this;
}
template<typename T>
template<typename U>
SparsePtr<T>& SparsePtr<T>::operator-=(U count)
{
static_assert(std::is_integral_v<U>, "count must be an integral type");
m_ptr -= count * m_stride;
return *this;
}
/*!
* \brief Gets the SparsePtr with the next element
* \return A reference to this pointer updated
*/
template<typename T>
SparsePtr<T>& SparsePtr<T>::operator++()
{
m_ptr += m_stride;
return *this;
}
/*!
* \brief Gets the SparsePtr with the next element
* \return A SparsePtr not updated
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator++(int)
{
// We copy the object
SparsePtr tmp(*this);
// We modify it
operator++();
// We return the copy
return tmp;
}
/*!
* \brief Gets the SparsePtr with the previous element
* \return A reference to this pointer updated
*/
template<typename T>
SparsePtr<T>& SparsePtr<T>::operator--()
{
m_ptr -= m_stride;
return *this;
}
/*!
* \brief Gets the SparsePtr with the previous element
* \return A SparsePtr not updated
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator--(int)
{
// We copy the object
SparsePtr tmp(*this);
// We modify it
operator--();
// We return the copy
return tmp;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the two SparsePtr are pointing to the same memory
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator==(const SparsePtr& ptr) const
{
return m_ptr == ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return false if the two SparsePtr are pointing to the same memory
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator!=(const SparsePtr& ptr) const
{
return m_ptr != ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory inferior to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator<(const SparsePtr& ptr) const
{
return m_ptr < ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory superior to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator>(const SparsePtr& ptr) const
{
return m_ptr > ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory inferior or equal to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator<=(const SparsePtr& ptr) const
{
return m_ptr <= ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory superior or equal to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator>=(const SparsePtr& ptr) const
{
return m_ptr >= ptr.m_ptr;
}
}
namespace std
{
template<typename T>
struct iterator_traits<Nz::SparsePtr<T>>
{
using difference_type = ptrdiff_t;
using iterator_category = random_access_iterator_tag;
using reference = const T&;
using pointer = const T*;
using value_type = T;
};
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -1,100 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_STACKARRAY_HPP
#define NAZARA_CORE_STACKARRAY_HPP
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#ifdef NAZARA_ALLOCA_SUPPORT
#define NazaraStackArray(T, size) Nz::StackArray<T>(static_cast<T*>(NAZARA_ALLOCA((size) * sizeof(T))), size)
#define NazaraStackArrayNoInit(T, size) Nz::StackArray<T>(static_cast<T*>(NAZARA_ALLOCA((size) * sizeof(T))), size, typename Nz::StackArray<T>::NoInitTag())
#else
#define NazaraStackArray(T, size) Nz::StackArray<T>(static_cast<T*>(Nz::OperatorNew((size) * sizeof(T))), size)
#define NazaraStackArrayNoInit(T, size) Nz::StackArray<T>(static_cast<T*>(Nz::OperatorNew((size) * sizeof(T))), size, typename Nz::StackArray<T>::NoInitTag())
#endif
#include <cstddef>
#include <iterator>
namespace Nz
{
template<typename T>
class StackArray
{
public:
struct NoInitTag {};
using value_type = T;
using const_iterator = const value_type*;
using const_pointer = const value_type*;
using const_reference = const value_type&;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using difference_type = std::ptrdiff_t;
using iterator = value_type*;
using pointer = value_type*;
using reference = value_type&;
using reverse_iterator = std::reverse_iterator<iterator>;
using size_type = std::size_t;
StackArray();
StackArray(T* stackMemory, std::size_t size);
StackArray(T* stackMemory, std::size_t size, NoInitTag);
StackArray(const StackArray&) = delete;
StackArray(StackArray&&) = default;
~StackArray();
reference back();
const_reference back() const;
iterator begin() noexcept;
const_iterator begin() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
T* data() noexcept;
const T* data() const noexcept;
bool empty() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
void fill(const T& value);
reference front() noexcept;
const_reference front() const noexcept;
size_type max_size() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
size_type size() const noexcept;
reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
StackArray& operator=(const StackArray&) = delete;
StackArray& operator=(StackArray&&) = default;
private:
std::size_t m_size;
MovablePtr<T> m_ptr;
};
}
#include <Nazara/Core/StackArray.inl>
#endif // NAZARA_CORE_STACKARRAY_HPP

View File

@ -1,216 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// I'm not proud of those five following lines but ti's hard to do with another way now
#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#else
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/Core/MemoryManager.hpp>
#include <algorithm>
#include <cassert>
#include <new>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::StackArray
* \brief Core class that represents a stack-allocated (if alloca is present) array
*/
template<typename T>
StackArray<T>::StackArray() :
m_size(0),
m_ptr(nullptr)
{
}
template<typename T>
StackArray<T>::StackArray(T* stackMemory, std::size_t size) :
m_size(size),
m_ptr(stackMemory)
{
for (std::size_t i = 0; i < m_size; ++i)
PlacementNew(&m_ptr[i]);
}
template<typename T>
StackArray<T>::StackArray(T* stackMemory, std::size_t size, NoInitTag) :
m_size(size),
m_ptr(stackMemory)
{
}
template<typename T>
StackArray<T>::~StackArray()
{
for (std::size_t i = 0; i < m_size; ++i)
PlacementDestroy(&m_ptr[i]);
#ifndef NAZARA_ALLOCA_SUPPORT
OperatorDelete(m_ptr);
#endif
}
template<typename T>
typename StackArray<T>::reference StackArray<T>::back()
{
assert(m_size != 0);
return m_ptr[m_size - 1];
}
template<typename T>
typename StackArray<T>::const_reference StackArray<T>::back() const
{
assert(m_size != 0);
return m_ptr[m_size - 1];
}
template<typename T>
typename StackArray<T>::iterator StackArray<T>::begin() noexcept
{
return iterator(&m_ptr[0]);
}
template<typename T>
typename StackArray<T>::const_iterator StackArray<T>::begin() const noexcept
{
return const_iterator(&m_ptr[0]);
}
template<typename T>
typename StackArray<T>::const_iterator StackArray<T>::cbegin() const noexcept
{
return const_iterator(&m_ptr[0]);
}
template<typename T>
typename StackArray<T>::const_iterator StackArray<T>::cend() const noexcept
{
return const_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackArray<T>::const_reverse_iterator StackArray<T>::crbegin() const noexcept
{
return const_reverse_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackArray<T>::const_reverse_iterator StackArray<T>::crend() const noexcept
{
return const_reverse_iterator(&m_ptr[0]);
}
template<typename T>
T* StackArray<T>::data() noexcept
{
return m_ptr;
}
template<typename T>
const T* StackArray<T>::data() const noexcept
{
return m_ptr;
}
template<typename T>
bool StackArray<T>::empty() const noexcept
{
return m_size == 0;
}
template<typename T>
typename StackArray<T>::iterator StackArray<T>::end() noexcept
{
return iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackArray<T>::const_iterator StackArray<T>::end() const noexcept
{
return const_iterator(&m_ptr[m_size]);
}
template<typename T>
void StackArray<T>::fill(const T& value)
{
std::fill(begin(), end(), value);
}
template<typename T>
typename StackArray<T>::reference StackArray<T>::front() noexcept
{
return m_ptr[0];
}
template<typename T>
typename StackArray<T>::const_reference StackArray<T>::front() const noexcept
{
return m_ptr[0];
}
template<typename T>
typename StackArray<T>::size_type StackArray<T>::max_size() const noexcept
{
return size();
}
template<typename T>
typename StackArray<T>::reverse_iterator StackArray<T>::rbegin() noexcept
{
return reverse_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackArray<T>::const_reverse_iterator StackArray<T>::rbegin() const noexcept
{
return reverse_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackArray<T>::reverse_iterator StackArray<T>::rend() noexcept
{
return reverse_iterator(&m_ptr[0]);
}
template<typename T>
typename StackArray<T>::const_reverse_iterator StackArray<T>::rend() const noexcept
{
return reverse_iterator(&m_ptr[0]);
}
template<typename T>
typename StackArray<T>::size_type StackArray<T>::size() const noexcept
{
return m_size;
}
template<typename T>
typename StackArray<T>::reference StackArray<T>::operator[](size_type pos)
{
assert(pos < m_size);
return m_ptr[pos];
}
template<typename T>
typename StackArray<T>::const_reference StackArray<T>::operator[](size_type pos) const
{
assert(pos < m_size);
return m_ptr[pos];
}
}
#include <Nazara/Core/DebugOff.hpp>
// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine)
#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif

View File

@ -1,119 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_STACKVECTOR_HPP
#define NAZARA_CORE_STACKVECTOR_HPP
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#ifdef NAZARA_ALLOCA_SUPPORT
#define NazaraStackVector(T, capacity) Nz::StackVector<T>(static_cast<T*>(NAZARA_ALLOCA((capacity) * sizeof(T))), capacity)
#else
#define NazaraStackVector(T, capacity) Nz::StackVector<T>(static_cast<T*>(Nz::OperatorNew((capacity) * sizeof(T))), capacity)
#endif
#include <cstddef>
#include <iterator>
#include <type_traits>
namespace Nz
{
template<typename T>
class StackVector
{
public:
using value_type = T;
using const_iterator = const value_type*;
using const_pointer = const value_type*;
using const_reference = const value_type&;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using difference_type = std::ptrdiff_t;
using iterator = value_type*;
using pointer = value_type*;
using reference = value_type&;
using reverse_iterator = std::reverse_iterator<iterator>;
using size_type = std::size_t;
StackVector();
StackVector(T* stackMemory, std::size_t capacity);
StackVector(const StackVector&) = delete;
StackVector(StackVector&&) = default;
~StackVector();
reference back();
const_reference back() const;
iterator begin() noexcept;
const_iterator begin() const noexcept;
size_type capacity() const noexcept;
void clear() noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
T* data() noexcept;
const T* data() const noexcept;
template<typename... Args>
iterator emplace(const_iterator pos, Args&&... args);
template<typename... Args>
reference emplace_back(Args&&... args);
bool empty() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
iterator erase(const_iterator pos);
iterator erase(const_iterator first, const_iterator last);
reference front() noexcept;
const_reference front() const noexcept;
iterator insert(const_iterator pos, const T& value);
iterator insert(const_iterator pos, T&& value);
size_type max_size() const noexcept;
reference push_back(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value);
reference push_back(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value);
void pop_back();
void resize(size_type count);
void resize(size_type count, const value_type& value);
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
size_type size() const noexcept;
reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
StackVector& operator=(const StackVector&) = delete;
StackVector& operator=(StackVector&&) = default;
private:
std::size_t m_capacity;
std::size_t m_size;
MovablePtr<T> m_ptr;
};
}
#include <Nazara/Core/StackVector.inl>
#endif // NAZARA_CORE_STACKVECTOR_HPP

View File

@ -1,347 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// I'm not proud of those five following lines but ti's hard to do with another way now
#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#else
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/Core/MemoryManager.hpp>
#include <algorithm>
#include <cassert>
#include <new>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::StackVector
* \brief Core class that represents a stack-allocated (if alloca is present) vector, that is with a capacity different from its size
*/
template<typename T>
StackVector<T>::StackVector() :
m_capacity(0),
m_size(0),
m_ptr(nullptr)
{
}
template<typename T>
StackVector<T>::StackVector(T* stackMemory, std::size_t capacity) :
m_capacity(capacity),
m_size(0),
m_ptr(stackMemory)
{
}
template<typename T>
StackVector<T>::~StackVector()
{
clear();
#ifndef NAZARA_ALLOCA_SUPPORT
OperatorDelete(m_ptr);
#endif
}
template<typename T>
typename StackVector<T>::reference StackVector<T>::back()
{
assert(m_size != 0);
return m_ptr[m_size - 1];
}
template<typename T>
typename StackVector<T>::const_reference StackVector<T>::back() const
{
assert(m_size != 0);
return m_ptr[m_size - 1];
}
template<typename T>
typename StackVector<T>::iterator StackVector<T>::begin() noexcept
{
return iterator(&m_ptr[0]);
}
template<typename T>
typename StackVector<T>::const_iterator StackVector<T>::begin() const noexcept
{
return const_iterator(&m_ptr[0]);
}
template<typename T>
typename StackVector<T>::size_type StackVector<T>::capacity() const noexcept
{
return m_capacity;
}
template<typename T>
void StackVector<T>::clear() noexcept
{
resize(0);
}
template<typename T>
typename StackVector<T>::const_iterator StackVector<T>::cbegin() const noexcept
{
return const_iterator(&m_ptr[0]);
}
template<typename T>
typename StackVector<T>::const_iterator StackVector<T>::cend() const noexcept
{
return const_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackVector<T>::const_reverse_iterator StackVector<T>::crbegin() const noexcept
{
return const_reverse_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackVector<T>::const_reverse_iterator StackVector<T>::crend() const noexcept
{
return const_reverse_iterator(&m_ptr[0]);
}
template<typename T>
T* StackVector<T>::data() noexcept
{
return m_ptr;
}
template<typename T>
const T* StackVector<T>::data() const noexcept
{
return m_ptr;
}
template<typename T>
template<typename... Args>
typename StackVector<T>::iterator StackVector<T>::emplace(const_iterator pos, Args&& ...args)
{
assert(m_size < m_capacity);
assert(pos >= begin() && pos <= end());
std::size_t index = std::distance(cbegin(), pos);
if (pos < end())
{
iterator lastElement = end() - 1;
PlacementNew(&m_ptr[m_size], std::move(*lastElement));
if (&m_ptr[index] < lastElement)
std::move_backward(&m_ptr[index], &m_ptr[m_size - 1], &m_ptr[m_size]);
PlacementDestroy(&m_ptr[index]);
}
m_size++;
return PlacementNew(&m_ptr[index], std::forward<Args>(args)...);
}
template<typename T>
template<typename... Args>
typename StackVector<T>::reference Nz::StackVector<T>::emplace_back(Args&&... args)
{
assert(m_size < m_capacity);
return *PlacementNew(&m_ptr[m_size++], std::forward<Args>(args)...);
}
template<typename T>
bool StackVector<T>::empty() const noexcept
{
return m_size == 0;
}
template<typename T>
typename StackVector<T>::iterator StackVector<T>::end() noexcept
{
return iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackVector<T>::const_iterator StackVector<T>::end() const noexcept
{
return const_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackVector<T>::iterator StackVector<T>::erase(const_iterator pos)
{
assert(pos < end());
std::size_t index = std::distance(cbegin(), pos);
std::move(begin() + index + 1, end(), begin() + index);
pop_back();
return iterator(&m_ptr[index]);
}
template<typename T>
typename StackVector<T>::iterator StackVector<T>::erase(const_iterator first, const_iterator last)
{
std::size_t index = std::distance(cbegin(), first);
if (first == last)
return begin() + index;
assert(first < last);
assert(first >= begin() && last <= end());
std::size_t count = std::distance(first, last);
std::move(begin() + index + count, end(), begin() + index);
resize(size() - count);
return iterator(&m_ptr[index]);
}
template<typename T>
typename StackVector<T>::reference StackVector<T>::front() noexcept
{
return m_ptr[0];
}
template<typename T>
typename StackVector<T>::const_reference StackVector<T>::front() const noexcept
{
return m_ptr[0];
}
template<typename T>
typename StackVector<T>::iterator StackVector<T>::insert(const_iterator pos, const T& value)
{
return emplace(pos, value);
}
template<typename T>
typename StackVector<T>::iterator StackVector<T>::insert(const_iterator pos, T&& value)
{
return emplace(pos, std::move(value));
}
template<typename T>
typename StackVector<T>::size_type StackVector<T>::max_size() const noexcept
{
return capacity();
}
template<typename T>
typename StackVector<T>::reference StackVector<T>::push_back(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value)
{
assert(m_size < m_capacity);
return *PlacementNew(&m_ptr[m_size++], value);
}
template<typename T>
typename StackVector<T>::reference StackVector<T>::push_back(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value)
{
assert(m_size < m_capacity);
return *PlacementNew(&m_ptr[m_size++], std::move(value));
}
template<typename T>
void StackVector<T>::pop_back()
{
assert(!empty());
PlacementDestroy(&m_ptr[--m_size]);
}
template<typename T>
void StackVector<T>::resize(size_type count)
{
assert(count <= m_capacity);
if (count > m_size)
{
for (std::size_t i = m_size; i < count; ++i)
PlacementNew(&m_ptr[i]);
m_size = count;
}
else if (count < m_size)
{
for (std::size_t i = count; i < m_size; ++i)
PlacementDestroy(&m_ptr[i]);
m_size = count;
}
}
template<typename T>
void StackVector<T>::resize(size_type count, const value_type& value)
{
assert(count <= m_capacity);
if (count > m_size)
{
for (std::size_t i = m_size; i < count; ++i)
PlacementNew(&m_ptr[i], value);
m_size = count;
}
else if (count < m_size)
{
for (std::size_t i = count; i < m_size; ++i)
PlacementDestroy(&m_ptr[i]);
m_size = count;
}
}
template<typename T>
typename StackVector<T>::reverse_iterator StackVector<T>::rbegin() noexcept
{
return reverse_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackVector<T>::const_reverse_iterator StackVector<T>::rbegin() const noexcept
{
return reverse_iterator(&m_ptr[m_size]);
}
template<typename T>
typename StackVector<T>::reverse_iterator StackVector<T>::rend() noexcept
{
return reverse_iterator(&m_ptr[0]);
}
template<typename T>
typename StackVector<T>::const_reverse_iterator StackVector<T>::rend() const noexcept
{
return reverse_iterator(&m_ptr[0]);
}
template<typename T>
typename StackVector<T>::size_type StackVector<T>::size() const noexcept
{
return m_size;
}
template<typename T>
typename StackVector<T>::reference StackVector<T>::operator[](size_type pos)
{
assert(pos < m_size);
return m_ptr[pos];
}
template<typename T>
typename StackVector<T>::const_reference StackVector<T>::operator[](size_type pos) const
{
assert(pos < m_size);
return m_ptr[pos];
}
}
#include <Nazara/Core/DebugOff.hpp>
// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine)
#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif

View File

@ -8,8 +8,9 @@
#define NAZARA_CORE_STREAM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Utils/Endianness.hpp>
#include <filesystem>
#include <memory>
#include <string>

View File

@ -1,79 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_TYPELIST_HPP
#define NAZARA_CORE_TYPELIST_HPP
#include <cstddef>
namespace Nz
{
template<typename...> struct TypeList {};
namespace Detail
{
template<typename, typename>
struct ListAppend;
template<typename, template<typename> typename>
struct ListApply;
template<typename, std::size_t>
struct ListAt;
template<typename, typename>
struct ListConcat;
template<typename, typename>
struct ListFind;
template<typename, template<typename...> typename>
struct ListInstantiate;
template<typename, typename>
struct ListPrepend;
template<typename>
struct ListSize;
template<typename, typename>
struct ListUnique;
}
template<typename List, typename NewType>
using TypeListAppend = typename Detail::ListAppend<List, NewType>::Result;
template<typename List, template<typename> typename Functor, typename... Args>
void TypeListApply(Args&&... args);
template<typename List, std::size_t Index>
using TypeListAt = typename Detail::ListAt<List, Index>::Type;
template<typename FirstList, typename SecondList>
using TypeListConcat = typename Detail::ListConcat<FirstList, SecondList>::Result;
template<typename List>
constexpr bool TypeListEmpty = Detail::ListSize<List>::Size == 0;
template<typename List, typename Type>
constexpr bool TypeListFind = Detail::ListFind<List, Type>::Find();
template<typename List, template<typename...> typename Class>
using TypeListInstantiate = typename Detail::ListInstantiate<List, Class>::Result;
template<typename List, typename NewType>
using TypeListPrepend = typename Detail::ListPrepend<List, NewType>::Result;
template<typename List>
constexpr std::size_t TypeListSize = Detail::ListSize<List>::Size;
template<typename List>
using TypeListUnique = typename Detail::ListUnique<TypeList<>, List>::Result;
}
#include <Nazara/Core/TypeList.inl>
#endif // NAZARA_CORE_TYPELIST_HPP

View File

@ -1,124 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/TypeList.hpp>
#include <type_traits>
#include <utility>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
namespace Detail
{
template<typename NewType, typename... ListTypes>
struct ListAppend<TypeList<ListTypes...>, NewType>
{
using Result = TypeList<ListTypes..., NewType>;
};
template<template<typename> typename Functor, typename T, typename... ListTypes>
struct ListApply<TypeList<T, ListTypes...>, Functor>
{
template<typename... Args>
static void Apply(Args&&... args)
{
Functor<T>()(std::forward<Args>(args)...);
if constexpr (sizeof...(ListTypes) > 0)
ListApply<TypeList<ListTypes...>, Functor>::Apply(std::forward<Args>(args)...);
}
};
template<typename T, typename... ListTypes>
struct ListAt<TypeList<T, ListTypes...>, 0>
{
using Type = T;
};
template<std::size_t Index, typename T, typename... ListTypes>
struct ListAt<TypeList<T, ListTypes...>, Index>
{
static_assert(Index <= sizeof...(ListTypes), "Index out of range");
using Type = typename ListAt<TypeList<ListTypes...>, Index - 1>::Type;
};
template<typename... First, typename... Second>
struct ListConcat<TypeList<First...>, TypeList<Second...>>
{
using Result = TypeList<First..., Second...>;
};
struct ListFindHelper
{
template<typename ToFind, typename Type, typename... Rest> static constexpr bool Find()
{
if constexpr (std::is_same_v<ToFind, Type>)
return true;
else
return Find<ToFind, Rest...>();
}
template<typename ToFind> static constexpr bool Find()
{
return false;
}
};
template<typename TypeToFind, typename... ListTypes>
struct ListFind<TypeList<ListTypes...>, TypeToFind>
{
static constexpr bool Find()
{
return ListFindHelper::Find<TypeToFind, ListTypes...>();
}
};
template<template<typename...> typename Class, typename... ListTypes>
struct ListInstantiate<TypeList<ListTypes...>, Class>
{
using Result = Class<ListTypes...>;
};
template<typename NewType, typename... ListTypes>
struct ListPrepend<TypeList<ListTypes...>, NewType>
{
using Result = TypeList<NewType, ListTypes...>;
};
template<typename... ListTypes>
struct ListSize<TypeList<ListTypes...>>
{
static constexpr std::size_t Size = sizeof...(ListTypes);
};
template<typename... Types, typename T1>
struct ListUnique<TypeList<Types...>, TypeList<T1>>
{
static constexpr bool IsTypePresent = ListFind<TypeList<Types...>, T1>::Find();
using Result = std::conditional_t<!IsTypePresent, TypeList<Types..., T1>, TypeList<Types...>>;
};
template<typename... Types, typename T1, typename T2, typename... Rest>
struct ListUnique<TypeList<Types...>, TypeList<T1, T2, Rest...>>
{
using Result = typename ListUnique<typename ListUnique<TypeList<Types...>, TypeList<T1>>::Result, TypeList<T2, Rest...>>::Result;
};
}
template<typename List, template<typename> typename Functor, typename... Args>
void TypeListApply(Args&&... args)
{
if constexpr (!TypeListEmpty<List>)
Detail::ListApply<List, Functor>::Apply(std::forward<Args>(args)...);
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -1,19 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CORE_TYPETAG_HPP
#define NAZARA_CORE_TYPETAG_HPP
namespace Nz
{
template<typename T>
struct TypeTag
{
using Type = T;
};
}
#endif // NAZARA_CORE_TYPETAG_HPP

View File

@ -8,6 +8,7 @@
#define NAZARA_CORE_UPDATABLE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Config.hpp>
namespace Nz
{

View File

@ -10,10 +10,13 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
namespace Nz
namespace nzsl
{
class FieldOffsets;
}
namespace Nz
{
class NAZARA_GRAPHICS_API BasicMaterial
{
friend class MaterialPipeline;
@ -94,7 +97,7 @@ namespace Nz
static MaterialSettings::Builder Build(BasicBuildOptions& options);
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
static std::pair<BasicUniformOffsets, FieldOffsets> BuildUniformOffsets();
static std::pair<BasicUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
std::size_t m_uniformBlockIndex;
BasicOptionIndexes m_basicOptionIndexes;

View File

@ -62,7 +62,7 @@ namespace Nz
{
NazaraAssert(HasAlphaTest(), "Material has no alpha test option");
const auto& optionOpt = m_material.GetOptionValue(m_basicOptionIndexes.alphaTest);
if (std::holds_alternative<ShaderAst::NoValue>(optionOpt))
if (std::holds_alternative<nzsl::Ast::NoValue>(optionOpt))
return false;
return std::get<bool>(optionOpt);

View File

@ -8,7 +8,7 @@
#define NAZARA_GRAPHICS_ENUMS_HPP
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Utils/Flags.hpp>
namespace Nz
{

View File

@ -8,7 +8,6 @@
#define NAZARA_GRAPHICS_FORWARDFRAMEPIPELINE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Graphics/BakedFrameGraph.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/DepthPipelinePass.hpp>
@ -22,6 +21,7 @@
#include <Nazara/Graphics/RenderQueue.hpp>
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Utils/MemoryPool.hpp>
#include <memory>
#include <optional>
#include <unordered_map>

View File

@ -15,7 +15,7 @@
#include <Nazara/Renderer/RenderPassCache.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Shader/FilesystemModuleResolver.hpp>
#include <NZSL/FilesystemModuleResolver.hpp>
#include <optional>
namespace Nz
@ -46,7 +46,7 @@ namespace Nz
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
inline const RenderPassCache& GetRenderPassCache() const;
inline TextureSamplerCache& GetSamplerCache();
inline const std::shared_ptr<FilesystemModuleResolver>& GetShaderModuleResolver() const;
inline const std::shared_ptr<nzsl::FilesystemModuleResolver>& GetShaderModuleResolver() const;
struct Config
{
@ -70,7 +70,7 @@ namespace Nz
std::optional<RenderPassCache> m_renderPassCache;
std::optional<TextureSamplerCache> m_samplerCache;
std::shared_ptr<FilesystemModuleResolver> m_shaderModuleResolver;
std::shared_ptr<nzsl::FilesystemModuleResolver> m_shaderModuleResolver;
std::shared_ptr<RenderBuffer> m_fullscreenVertexBuffer;
std::shared_ptr<RenderDevice> m_renderDevice;
std::shared_ptr<RenderPipeline> m_blitPipeline;

View File

@ -63,7 +63,7 @@ namespace Nz
return *m_samplerCache;
}
inline const std::shared_ptr<FilesystemModuleResolver>& Graphics::GetShaderModuleResolver() const
inline const std::shared_ptr<nzsl::FilesystemModuleResolver>& Graphics::GetShaderModuleResolver() const
{
return m_shaderModuleResolver;
}

View File

@ -8,9 +8,9 @@
#define NAZARA_GRAPHICS_INSTANCEDRENDERABLE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Math/Box.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <memory>
namespace Nz

View File

@ -8,11 +8,11 @@
#define NAZARA_GRAPHICS_LIGHT_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Math/BoundingVolume.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <memory>
namespace Nz

View File

@ -14,14 +14,14 @@
#include <Nazara/Core/ResourceLoader.hpp>
#include <Nazara/Core/ResourceManager.hpp>
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/MaterialPipeline.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Shader/Ast/ConstantValue.hpp>
#include <Nazara/Utility/UniformBuffer.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <NZSL/Ast/ConstantValue.hpp>
#include <array>
#include <string>
#include <vector>
@ -67,13 +67,13 @@ namespace Nz
inline FaceFilling GetFaceFilling() const;
inline MaterialPassFlags GetFlags() const;
inline float GetLineWidth() const;
inline const ShaderAst::ConstantValue& GetOptionValue(std::size_t optionIndex) const;
inline const nzsl::Ast::ConstantValue& GetOptionValue(std::size_t optionIndex) const;
inline const std::shared_ptr<MaterialPipeline>& GetPipeline() const;
inline const MaterialPipelineInfo& GetPipelineInfo() const;
inline float GetPointSize() const;
inline PrimitiveMode GetPrimitiveMode() const;
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
inline const std::shared_ptr<UberShader>& GetShader(nzsl::ShaderStageType shaderStage) const;
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
inline const std::shared_ptr<RenderBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
@ -98,7 +98,7 @@ namespace Nz
inline void SetFaceCulling(FaceSide faceSide);
inline void SetFaceFilling(FaceFilling filling);
inline void SetLineWidth(float lineWidth);
inline void SetOptionValue(std::size_t optionIndex, ShaderAst::ConstantValue value);
inline void SetOptionValue(std::size_t optionIndex, nzsl::Ast::ConstantValue value);
inline void SetPointSize(float pointSize);
inline void SetPrimitiveMode(PrimitiveMode mode);
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
@ -142,7 +142,7 @@ namespace Nz
bool dataInvalidated = true;
};
std::array<ShaderAst::ConstantValue, 64> m_optionValues;
std::array<nzsl::Ast::ConstantValue, 64> m_optionValues;
std::shared_ptr<const MaterialSettings> m_settings;
std::vector<MaterialTexture> m_textures;
std::vector<ShaderEntry> m_shaders;

View File

@ -319,7 +319,7 @@ namespace Nz
return m_pipelineInfo.lineWidth;
}
inline const ShaderAst::ConstantValue& MaterialPass::GetOptionValue(std::size_t optionIndex) const
inline const nzsl::Ast::ConstantValue& MaterialPass::GetOptionValue(std::size_t optionIndex) const
{
assert(optionIndex < m_optionValues.size());
return m_optionValues[optionIndex];
@ -368,7 +368,7 @@ namespace Nz
* \brief Gets the über-shader used by this material
* \return Constant pointer to the über-shader used
*/
inline const std::shared_ptr<UberShader>& MaterialPass::GetShader(ShaderStageType shaderStage) const
inline const std::shared_ptr<UberShader>& MaterialPass::GetShader(nzsl::ShaderStageType shaderStage) const
{
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
}
@ -566,7 +566,7 @@ namespace Nz
InvalidatePipeline();
}
inline void MaterialPass::SetOptionValue(std::size_t optionIndex, ShaderAst::ConstantValue value)
inline void MaterialPass::SetOptionValue(std::size_t optionIndex, nzsl::Ast::ConstantValue value)
{
assert(optionIndex < m_optionValues.size());
if (m_optionValues[optionIndex] != value)

View File

@ -12,7 +12,7 @@
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Shader/Ast/ConstantValue.hpp>
#include <NZSL/Ast/ConstantValue.hpp>
#include <array>
#include <memory>
@ -25,7 +25,7 @@ namespace Nz
struct Option
{
UInt32 hash;
ShaderAst::ConstantValue value;
nzsl::Ast::ConstantValue value;
};
struct Shader

View File

@ -41,7 +41,7 @@ namespace Nz
inline std::size_t GetOptionIndex(const std::string_view& name) const;
inline std::size_t GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType stage) const;
inline const std::shared_ptr<UberShader>& GetShader(nzsl::ShaderStageType stage) const;
inline const std::vector<std::shared_ptr<UberShader>>& GetShaders() const;
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
inline std::size_t GetSharedUniformBlockIndex(const std::string_view& name) const;
@ -88,7 +88,7 @@ namespace Nz
UInt32 bindingIndex;
std::string name;
std::vector<UniformVariable> uniforms;
ShaderStageTypeFlags shaderStages = ShaderStageType_All;
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
};
struct Texture
@ -96,7 +96,7 @@ namespace Nz
UInt32 bindingIndex;
std::string name;
ImageType type;
ShaderStageTypeFlags shaderStages = ShaderStageType_All;
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
};
struct UniformBlock
@ -106,7 +106,7 @@ namespace Nz
std::size_t blockSize;
std::vector<UniformVariable> uniforms;
std::vector<UInt8> defaultValues;
ShaderStageTypeFlags shaderStages = ShaderStageType_All;
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
};
private:

View File

@ -84,7 +84,7 @@ namespace Nz
return m_pipelineLayout;
}
inline const std::shared_ptr<UberShader>& MaterialSettings::GetShader(ShaderStageType stage) const
inline const std::shared_ptr<UberShader>& MaterialSettings::GetShader(nzsl::ShaderStageType stage) const
{
return m_data.shaders[UnderlyingCast(stage)];
}

View File

@ -92,7 +92,7 @@ namespace Nz
static MaterialSettings::Builder Build(PhongBuildOptions& options);
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
static std::pair<PhongUniformOffsets, FieldOffsets> BuildUniformOffsets();
static std::pair<PhongUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
private:
static bool Initialize();

View File

@ -35,7 +35,7 @@ namespace Nz
static constexpr std::size_t MaxLightCount = 3;
static PredefinedLightData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
struct NAZARA_GRAPHICS_API PredefinedInstanceData
@ -45,7 +45,7 @@ namespace Nz
std::size_t worldMatrixOffset;
static PredefinedInstanceData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
struct NAZARA_GRAPHICS_API PredefinedViewerData
@ -62,7 +62,7 @@ namespace Nz
std::size_t viewProjMatrixOffset;
static PredefinedViewerData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, ShaderStageTypeFlags shaderStages);
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
}

View File

@ -8,11 +8,11 @@
#define NAZARA_GRAPHICS_SYSTEMS_RENDERSYSTEM_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Graphics/Components/LightComponent.hpp>
#include <Nazara/Utility/Node.hpp>
#include <Nazara/Utils/MemoryPool.hpp>
#include <entt/entt.hpp>
#include <array>
#include <memory>

View File

@ -9,12 +9,11 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Shader/ShaderModuleResolver.hpp>
#include <Nazara/Shader/Ast/Module.hpp>
#include <Nazara/Utils/Signal.hpp>
#include <NZSL/ShaderModuleResolver.hpp>
#include <NZSL/Ast/Module.hpp>
#include <unordered_map>
namespace Nz
@ -28,12 +27,12 @@ namespace Nz
struct Option;
using ConfigCallback = std::function<void(Config& config, const std::vector<RenderPipelineInfo::VertexBufferData>& vertexBuffers)>;
UberShader(ShaderStageTypeFlags shaderStages, std::string moduleName);
UberShader(ShaderStageTypeFlags shaderStages, ShaderModuleResolver& moduleResolver, std::string moduleName);
UberShader(ShaderStageTypeFlags shaderStages, ShaderAst::ModulePtr shaderModule);
UberShader(nzsl::ShaderStageTypeFlags shaderStages, std::string moduleName);
UberShader(nzsl::ShaderStageTypeFlags shaderStages, nzsl::ShaderModuleResolver& moduleResolver, std::string moduleName);
UberShader(nzsl::ShaderStageTypeFlags shaderStages, nzsl::Ast::ModulePtr shaderModule);
~UberShader() = default;
inline ShaderStageTypeFlags GetSupportedStages() const;
inline nzsl::ShaderStageTypeFlags GetSupportedStages() const;
const std::shared_ptr<ShaderModule>& Get(const Config& config);
@ -44,7 +43,7 @@ namespace Nz
struct Config
{
std::unordered_map<UInt32, ShaderAst::ConstantValue> optionValues;
std::unordered_map<UInt32, nzsl::Ast::ConstantValue> optionValues;
};
struct ConfigEqual
@ -65,15 +64,15 @@ namespace Nz
NazaraSignal(OnShaderUpdated, UberShader* /*uberShader*/);
private:
ShaderAst::ModulePtr Validate(const ShaderAst::Module& module, std::unordered_map<std::string, Option>* options);
nzsl::Ast::ModulePtr Validate(const nzsl::Ast::Module& module, std::unordered_map<std::string, Option>* options);
NazaraSlot(ShaderModuleResolver, OnModuleUpdated, m_onShaderModuleUpdated);
NazaraSlot(nzsl::ShaderModuleResolver, OnModuleUpdated, m_onShaderModuleUpdated);
std::unordered_map<Config, std::shared_ptr<ShaderModule>, ConfigHasher, ConfigEqual> m_combinations;
std::unordered_map<std::string, Option> m_optionIndexByName;
ShaderAst::ModulePtr m_shaderModule;
nzsl::Ast::ModulePtr m_shaderModule;
ConfigCallback m_configCallback;
ShaderStageTypeFlags m_shaderStages;
nzsl::ShaderStageTypeFlags m_shaderStages;
};
}

View File

@ -7,7 +7,7 @@
namespace Nz
{
inline ShaderStageTypeFlags UberShader::GetSupportedStages() const
inline nzsl::ShaderStageTypeFlags UberShader::GetSupportedStages() const
{
return m_shaderStages;
}

View File

@ -9,27 +9,17 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Enums.hpp>
#include <Nazara/Utils/Algorithm.hpp>
#include <cmath>
#include <limits>
#include <string>
namespace Nz
{
template<typename T> constexpr T HalfPi = T(1.5707963267948966192313216916398);
template<typename T> constexpr T Pi = T(3.1415926535897932384626433832795);
template<typename T> constexpr T Sqrt2 = T(1.4142135623730950488016887242097);
template<typename T> constexpr T Sqrt3 = T(1.7320508075688772935274463415059);
template<typename T> constexpr T Sqrt5 = T(2.2360679774997896964091736687313);
template<AngleUnit Unit, typename T> class Angle;
template<typename T> constexpr T Approach(T value, T objective, T increment);
template<typename T> constexpr T Clamp(T value, T min, T max);
template<typename T, AngleUnit Unit> constexpr Angle<Unit, T> Clamp(Angle<Unit, T> value, T min, T max);
template<typename T> T ClearBit(T number, T bit);
template<typename T> constexpr std::size_t CountBits(T value);
template<typename T> constexpr T DegreeToRadian(T degrees);
template<typename T> constexpr T GetNearestPowerOfTwo(T number);
constexpr unsigned int GetNumberLength(signed char number);
constexpr unsigned int GetNumberLength(unsigned char number);
unsigned int GetNumberLength(int number);
@ -39,19 +29,8 @@ namespace Nz
unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
template<typename T> constexpr unsigned int IntegralLog2(T number);
template<typename T> constexpr unsigned int IntegralLog2Pot(T pot);
template<typename T> constexpr T IntegralPow(T base, unsigned int exponent);
template<typename T, typename T2> constexpr T Lerp(const T& from, const T& to, const T2& interpolation);
template<typename T> constexpr T MultiplyAdd(T x, T y, T z);
template<typename T> constexpr bool NumberEquals(T a, T b);
template<typename T> constexpr bool NumberEquals(T a, T b, T maxDifference);
inline std::string NumberToString(long long number, UInt8 radix = 10);
template<typename T> constexpr T RadianToDegree(T radians);
template<typename T> T SetBit(T number, T bit);
inline long long StringToNumber(const std::string_view& str, UInt8 radix = 10, bool* ok = nullptr);
template<typename T> bool TestBit(T number, T bit);
template<typename T> T ToggleBit(T number, T bit);
}
#include <Nazara/Math/Algorithm.inl>

View File

@ -13,149 +13,6 @@
namespace Nz
{
namespace Detail
{
namespace
{
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
static constexpr unsigned int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
static constexpr unsigned int MultiplyDeBruijnBitPosition2[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
}
template<typename T>
constexpr std::enable_if_t<sizeof(T) <= sizeof(UInt32), unsigned int> IntegralLog2(T number)
{
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
number |= number >> 1; // first round down to one less than a power of 2
number |= number >> 2;
number |= number >> 4;
number |= number >> 8;
number |= number >> 16;
return MultiplyDeBruijnBitPosition[static_cast<UInt32>(number * 0x07C4ACDDU) >> 27];
}
template<typename T>
constexpr std::enable_if_t<(sizeof(T) > sizeof(UInt32)), unsigned int> IntegralLog2(T number)
{
static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed");
// Masking and shifting bits to the right (to bring it back to 32 bits)
// Call of the function with 32 bits number, if the result is non-null we have our answer
for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32))
{
// The 32 bits mask on the part we are treating
T mask = T(std::numeric_limits<UInt32>::max()) << i*8;
T val = (number & mask) >> i*8; // Masking and shifting bits to the right (to bring it back to 32 bits)
// Call of the function with 32 bits number, if the result is non-null we have our answer
unsigned int log2 = IntegralLog2<UInt32>(val);
if (log2)
return log2 + i*8;
}
return 0;
}
template<typename T>
constexpr std::enable_if_t<sizeof(T) <= sizeof(UInt32), unsigned int> IntegralLog2Pot(T number)
{
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
return MultiplyDeBruijnBitPosition2[static_cast<UInt32>(number * 0x077CB531U) >> 27];
}
template<typename T>
constexpr std::enable_if_t<(sizeof(T) > sizeof(UInt32)), unsigned int> IntegralLog2Pot(T number)
{
static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed");
// The algorithm for logarithm in base 2 only works with numbers greater than 32 bits
// This code subdivides the biggest number into 32 bits ones
for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32))
{
// The 32 bits mask on the part we are treating
T mask = T(std::numeric_limits<UInt32>::max()) << i*8;
UInt32 val = UInt32((number & mask) >> i*8); // Masking and shifting bits to the right (to bring it back to 32 bits)
// Call of the function with 32 bits number, if the result is non-null we have our answer
unsigned int log2 = IntegralLog2Pot<UInt32>(val);
if (log2 || val == 1)
return log2 + i*8;
}
return 0;
}
template<typename T> constexpr std::enable_if_t<std::is_floating_point<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
{
T diff = std::abs(a - b);
return diff <= maxDifference;
}
template<typename T> constexpr std::enable_if_t<!std::is_signed<T>::value || (!std::is_integral<T>::value && !std::is_floating_point<T>::value), bool> NumberEquals(T a, T b, T maxDifference)
{
if (b > a)
std::swap(a, b);
T diff = a - b;
return diff <= maxDifference;
}
template<typename T> constexpr std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
{
if (b > a)
std::swap(a, b);
using UnsignedT = std::make_unsigned_t<T>;
return static_cast<UnsignedT>(a) - static_cast<UnsignedT>(b) <= static_cast<UnsignedT>(maxDifference);
}
}
/*!
* \ingroup math
* \brief Approaches the objective, beginning with value and with increment
* \return The nearest value of the objective you can get with the value and the increment for one step
*
* \param value Initial value
* \param objective Target value
* \param increment One step value
*/
template<typename T>
constexpr inline T Approach(T value, T objective, T increment)
{
if (value < objective)
return std::min(value + increment, objective);
else if (value > objective)
return std::max(value - increment, objective);
else
return value;
}
/*!
* \ingroup math
* \brief Clamps value between min and max and returns the expected value
* \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval
*
* \param value Value to clamp
* \param min Minimum of the interval
* \param max Maximum of the interval
*/
template<typename T>
constexpr T Clamp(T value, T min, T max)
{
return std::max(std::min(value, max), min);
}
/*!
* \ingroup math
* \brief Clamps an angle value between min and max and returns the expected value
@ -171,64 +28,6 @@ namespace Nz
return std::max(std::min(value.value, max), min);
}
template<typename T>
T ClearBit(T number, T bit)
{
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
return number &= ~(T(1) << bit);
}
/*!
* \ingroup math
* \brief Gets number of bits set in the number
* \return The number of bits set to 1
*
* \param value The value to count bits
*/
template<typename T>
constexpr inline std::size_t CountBits(T value)
{
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
std::size_t count = 0;
while (value)
{
value &= value - 1;
count++;
}
return count;
}
/*!
* \ingroup math
* \brief Converts degree to radian
* \return The representation in radian of the angle in degree (0..2*pi)
*
* \param degrees Angle in degree (this is expected between 0..360)
*/
template<typename T>
constexpr T DegreeToRadian(T degrees)
{
return degrees * T(Pi<T>/180.0);
}
/*!
* \ingroup math
* \brief Gets the nearest power of two for the number
* \return First power of two containing the number
*
* \param number Number to get nearest power
*/
template<typename T>
constexpr inline T GetNearestPowerOfTwo(T number)
{
T x = 1;
while (x < number)
x <<= 1; // We multiply by 2
return x;
}
/*!
* \ingroup math
* \brief Gets the number of digits to represent the number in base 10
@ -379,147 +178,6 @@ namespace Nz
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
}
/*!
* \ingroup math
* \brief Gets the log in base 2 of integral number
* \return Log of the number (floor)
*
* \param number To get log in base 2
*
* \remark If number is 0, 0 is returned
*/
template<typename T>
constexpr unsigned int IntegralLog2(T number)
{
// Proxy needed to avoid an overload problem
return Detail::IntegralLog2<T>(number);
}
/*!
* \ingroup math
* \brief Gets the log in base 2 of integral number, only works for power of two !
* \return Log of the number
*
* \param pot To get log in base 2
*
* \remark Only works for power of two
* \remark If number is 0, 0 is returned
*/
template<typename T>
constexpr unsigned int IntegralLog2Pot(T pot)
{
return Detail::IntegralLog2Pot<T>(pot);
}
/*!
* \ingroup math
* \brief Gets the power of integrals
* \return base^exponent for integral
*
* \param base Base of the exponentation
* \param exponent Power for the base
*/
template<typename T>
constexpr T IntegralPow(T base, unsigned int exponent)
{
T r = 1;
for (unsigned int i = 0; i < exponent; ++i)
r *= base;
return r;
}
/*!
* \ingroup math
* \brief Interpolates the value to other one with a factor of interpolation
* \return A new value which is the interpolation of two values
*
* \param from Initial value
* \param to Target value
* \param interpolation Factor of interpolation
*
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
* \remark With NAZARA_DEBUG, a NazaraWarning is produced
*
* \see Lerp
*/
template<typename T, typename T2>
constexpr T Lerp(const T& from, const T& to, const T2& interpolation)
{
return static_cast<T>(from + interpolation * (to - from));
}
/*!
* \ingroup math
* \brief Multiplies X and Y, then add Z
* \return The result of X * Y + Z
*
* \param x is X
* \param y is Y
* \param z is Z
*
* \remark This function is meant to use a special faster instruction in CPU if possible
*/
template<typename T>
constexpr T MultiplyAdd(T x, T y, T z)
{
return x * y + z;
}
#ifdef FP_FAST_FMAF
template<>
constexpr float MultiplyAdd(float x, float y, float z)
{
return std::fmaf(x, y, z);
}
#endif
#ifdef FP_FAST_FMA
template<>
constexpr double MultiplyAdd(double x, double y, double z)
{
return std::fma(x, y, z);
}
#endif
#ifdef FP_FAST_FMAL
template<>
constexpr long double MultiplyAdd(long double x, long double y, long double z)
{
return std::fmal(x, y, z);
}
#endif
/*!
* \ingroup math
* \brief Checks whether two numbers are equal
* \return true if they are equal within a certain epsilon
*
* \param a First value
* \param b Second value
*/
template<typename T>
constexpr inline bool NumberEquals(T a, T b)
{
return NumberEquals(a, b, std::numeric_limits<T>::epsilon());
}
/*!
* \ingroup math
* \brief Checks whether two numbers are equal
* \return true if they are equal within the max difference
*
* \param a First value
* \param b Second value
* \param maxDifference Epsilon of comparison (expected to be positive)
*/
template<typename T>
constexpr inline bool NumberEquals(T a, T b, T maxDifference)
{
return Detail::NumberEquals(a, b, maxDifference);
}
/*!
* \ingroup math
* \brief Converts the number to String
@ -572,26 +230,6 @@ namespace Nz
return str;
}
/*!
* \ingroup math
* \brief Converts radian to degree
* \return The representation in degree of the angle in radian (0..360)
*
* \param radians Angle in radian (this is expected between 0..2*pi)
*/
template<typename T>
constexpr T RadianToDegree(T radians)
{
return radians * T(180.0/Pi<T>);
}
template<typename T>
T SetBit(T number, T bit)
{
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
return number |= (T(1) << bit);
}
/*!
* \ingroup math
* \brief Converts the string to number
@ -656,20 +294,6 @@ namespace Nz
return (negative) ? -static_cast<long long>(total) : total;
}
template<typename T>
bool TestBit(T number, T bit)
{
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
return number & (T(1) << bit);
}
template<typename T>
T ToggleBit(T number, T bit)
{
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
return number ^= (T(1) << bit);
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -7,9 +7,9 @@
#ifndef NAZARA_MATH_ANGLE_HPP
#define NAZARA_MATH_ANGLE_HPP
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Math/Enums.hpp>
#include <Nazara/Utils/TypeTag.hpp>
#include <ostream>
#include <string>
#include <type_traits>

View File

@ -9,9 +9,9 @@
///FIXME: Matrices column-major, difficile de bosser avec (Tout passer en row-major et transposer dans les shaders ?)
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Math/Angle.hpp>
#include <Nazara/Math/Config.hpp>
#include <Nazara/Utils/TypeTag.hpp>
#include <cstddef>
#include <string>

View File

@ -8,8 +8,8 @@
#define NAZARA_MATH_VECTOR2_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Math/Angle.hpp>
#include <Nazara/Utils/TypeTag.hpp>
#include <functional>
#include <string>

View File

@ -8,8 +8,8 @@
#define NAZARA_MATH_VECTOR3_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Math/Angle.hpp>
#include <Nazara/Utils/TypeTag.hpp>
#include <functional>
#include <string>

View File

@ -8,7 +8,7 @@
#define NAZARA_MATH_VECTOR4_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/TypeTag.hpp>
#include <Nazara/Utils/TypeTag.hpp>
#include <functional>
#include <string>

View File

@ -8,10 +8,10 @@
#define NAZARA_NETWORK_ABSTRACTSOCKET_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Network/Config.hpp>
#include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/SocketHandle.hpp>
#include <Nazara/Utils/Signal.hpp>
namespace Nz
{

View File

@ -3,7 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Algorithm.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Utils/Endianness.hpp>
#include <Nazara/Network/Debug.hpp>
namespace Nz

View File

@ -18,9 +18,7 @@
#define NAZARA_NETWORK_ENETHOST_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Network/ENetCompressor.hpp>
#include <Nazara/Network/ENetPeer.hpp>
#include <Nazara/Network/ENetProtocol.hpp>
@ -29,6 +27,8 @@
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/SocketPoller.hpp>
#include <Nazara/Network/UdpSocket.hpp>
#include <Nazara/Utils/Flags.hpp>
#include <Nazara/Utils/MemoryPool.hpp>
#include <random>
namespace Nz

View File

@ -8,8 +8,8 @@
#define NAZARA_NETWORK_ENETPACKET_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Utils/MemoryPool.hpp>
namespace Nz
{

View File

@ -18,11 +18,11 @@
#define NAZARA_NETWORK_ENETPEER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Network/ENetPacket.hpp>
#include <Nazara/Network/ENetProtocol.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Utils/Flags.hpp>
#include <Nazara/Utils/MovablePtr.hpp>
#include <array>
#include <list>
#include <random>

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