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:
parent
3f8f1c4653
commit
03e2801dbe
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -1,191 +1,191 @@
|
|||
#include <Nazara/Core.hpp>
|
||||
#include <Nazara/Platform.hpp>
|
||||
#include <Nazara/Graphics.hpp>
|
||||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
#include <Nazara/Graphics/Components.hpp>
|
||||
#include <Nazara/Graphics/Systems.hpp>
|
||||
#include <Nazara/Math/PidController.hpp>
|
||||
#include <Nazara/Core.hpp>
|
||||
#include <Nazara/Platform.hpp>
|
||||
#include <Nazara/Graphics.hpp>
|
||||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
#include <Nazara/Graphics/Components.hpp>
|
||||
#include <Nazara/Graphics/Systems.hpp>
|
||||
#include <Nazara/Math/PidController.hpp>
|
||||
#include <Nazara/Physics2D.hpp>
|
||||
#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 <Nazara/Utility.hpp>
|
||||
#include <Nazara/Utility/Components.hpp>
|
||||
#include <Nazara/Widgets.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
NAZARA_REQUEST_DEDICATED_GPU()
|
||||
|
||||
int main()
|
||||
{
|
||||
std::filesystem::path resourceDir = "resources";
|
||||
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory(".." / resourceDir))
|
||||
resourceDir = ".." / resourceDir;
|
||||
|
||||
Nz::Renderer::Config rendererConfig;
|
||||
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||
if (std::getchar() != 'n')
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||
else
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
Nz::Modules<Nz::Graphics, Nz::Physics2D> nazara(rendererConfig);
|
||||
|
||||
Nz::RenderWindow window;
|
||||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Graphics::Instance()->GetRenderDevice();
|
||||
|
||||
std::string windowTitle = "Graphics Test";
|
||||
if (!window.Create(device, Nz::VideoMode(1920, 1080, 32), windowTitle))
|
||||
{
|
||||
std::cout << "Failed to create Window" << std::endl;
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
entt::registry registry;
|
||||
|
||||
#include <Nazara/Physics2D/Components.hpp>
|
||||
#include <Nazara/Physics2D/Systems.hpp>
|
||||
#include <Nazara/Renderer.hpp>
|
||||
#include <NZSL/SpirvConstantCache.hpp>
|
||||
#include <NZSL/SpirvPrinter.hpp>
|
||||
#include <Nazara/Utility.hpp>
|
||||
#include <Nazara/Utility/Components.hpp>
|
||||
#include <Nazara/Widgets.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
NAZARA_REQUEST_DEDICATED_GPU()
|
||||
|
||||
int main()
|
||||
{
|
||||
std::filesystem::path resourceDir = "resources";
|
||||
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory(".." / resourceDir))
|
||||
resourceDir = ".." / resourceDir;
|
||||
|
||||
Nz::Renderer::Config rendererConfig;
|
||||
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||
if (std::getchar() != 'n')
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||
else
|
||||
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
Nz::Modules<Nz::Graphics, Nz::Physics2D> nazara(rendererConfig);
|
||||
|
||||
Nz::RenderWindow window;
|
||||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Graphics::Instance()->GetRenderDevice();
|
||||
|
||||
std::string windowTitle = "Graphics Test";
|
||||
if (!window.Create(device, Nz::VideoMode(1920, 1080, 32), windowTitle))
|
||||
{
|
||||
std::cout << "Failed to create Window" << std::endl;
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
entt::registry registry;
|
||||
|
||||
Nz::Physics2DSystem physSytem(registry);
|
||||
physSytem.GetPhysWorld().SetGravity({ 0.f, -9.81f });
|
||||
|
||||
Nz::RenderSystem renderSystem(registry);
|
||||
|
||||
entt::entity viewer = registry.create();
|
||||
{
|
||||
registry.emplace<Nz::NodeComponent>(viewer);
|
||||
auto& cameraComponent = registry.emplace<Nz::CameraComponent>(viewer, window.GetRenderTarget(), Nz::ProjectionType::Orthographic);
|
||||
cameraComponent.UpdateRenderMask(1);
|
||||
cameraComponent.UpdateClearColor(Nz::Color(0.5f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
|
||||
|
||||
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
|
||||
material->AddPass("ForwardPass", materialPass);
|
||||
|
||||
Nz::TextureSamplerInfo samplerInfo;
|
||||
samplerInfo.anisotropyLevel = 8;
|
||||
|
||||
Nz::TextureParams texParams;
|
||||
texParams.renderDevice = device;
|
||||
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
|
||||
|
||||
Nz::BasicMaterial basicMat(*materialPass);
|
||||
basicMat.SetDiffuseMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
|
||||
Nz::RenderSystem renderSystem(registry);
|
||||
|
||||
entt::entity viewer = registry.create();
|
||||
{
|
||||
registry.emplace<Nz::NodeComponent>(viewer);
|
||||
auto& cameraComponent = registry.emplace<Nz::CameraComponent>(viewer, window.GetRenderTarget(), Nz::ProjectionType::Orthographic);
|
||||
cameraComponent.UpdateRenderMask(1);
|
||||
cameraComponent.UpdateClearColor(Nz::Color(0.5f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
|
||||
|
||||
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
|
||||
material->AddPass("ForwardPass", materialPass);
|
||||
|
||||
Nz::TextureSamplerInfo samplerInfo;
|
||||
samplerInfo.anisotropyLevel = 8;
|
||||
|
||||
Nz::TextureParams texParams;
|
||||
texParams.renderDevice = device;
|
||||
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
|
||||
|
||||
Nz::BasicMaterial basicMat(*materialPass);
|
||||
basicMat.SetDiffuseMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
|
||||
basicMat.SetDiffuseSampler(samplerInfo);
|
||||
|
||||
for (std::size_t y = 0; y < 10; ++y)
|
||||
{
|
||||
for (std::size_t x = 0; x < 10; ++x)
|
||||
{
|
||||
entt::entity spriteEntity = registry.create();
|
||||
{
|
||||
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(material);
|
||||
sprite->SetSize({ 32.f, 32.f });
|
||||
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);
|
||||
}
|
||||
}
|
||||
{
|
||||
for (std::size_t x = 0; x < 10; ++x)
|
||||
{
|
||||
entt::entity spriteEntity = registry.create();
|
||||
{
|
||||
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(material);
|
||||
sprite->SetSize({ 32.f, 32.f });
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entt::entity groundEntity = registry.create();
|
||||
{
|
||||
std::shared_ptr<Nz::Material> whiteMaterial = std::make_shared<Nz::Material>();
|
||||
|
||||
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
|
||||
whiteMaterial->AddPass("ForwardPass", materialPass);
|
||||
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
|
||||
whiteMaterial->AddPass("ForwardPass", materialPass);
|
||||
|
||||
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(whiteMaterial);
|
||||
sprite->SetSize({ 800.f, 20.f });
|
||||
sprite->SetOrigin({ 400.f, 10.f, 0.f });
|
||||
|
||||
registry.emplace<Nz::NodeComponent>(groundEntity).SetPosition(1920.f / 2.f, 50.f);
|
||||
registry.emplace<Nz::NodeComponent>(groundEntity).SetPosition(1920.f / 2.f, 50.f);
|
||||
registry.emplace<Nz::GraphicsComponent>(groundEntity).AttachRenderable(sprite, 1);
|
||||
auto& rigidBody = registry.emplace<Nz::RigidBody2DComponent>(groundEntity, physSytem.CreateRigidBody(0.f, std::make_shared<Nz::BoxCollider2D>(Nz::Vector2f(800.f, 20.f))));
|
||||
rigidBody.SetElasticity(0.99f);
|
||||
}
|
||||
|
||||
Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f);
|
||||
Nz::Quaternionf camQuat(camAngles);
|
||||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
//Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
|
||||
Nz::PidController<Nz::Vector3f> headingController(0.5f, 0.f, 0.05f);
|
||||
Nz::PidController<Nz::Vector3f> upController(1.f, 0.f, 0.1f);
|
||||
|
||||
bool showColliders = false;
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
elapsedTime = (now - time) / 1'000'000.f;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
while (window.PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case Nz::WindowEventType::Quit:
|
||||
window.Close();
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::KeyPressed:
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::MouseMoved:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
|
||||
Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f);
|
||||
Nz::Quaternionf camQuat(camAngles);
|
||||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
//Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
|
||||
Nz::PidController<Nz::Vector3f> headingController(0.5f, 0.f, 0.05f);
|
||||
Nz::PidController<Nz::Vector3f> upController(1.f, 0.f, 0.1f);
|
||||
|
||||
bool showColliders = false;
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
elapsedTime = (now - time) / 1'000'000.f;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
while (window.PollEvent(&event))
|
||||
{
|
||||
float updateTime = updateClock.Restart() / 1'000'000.f;
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case Nz::WindowEventType::Quit:
|
||||
window.Close();
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::KeyPressed:
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::MouseMoved:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
{
|
||||
float updateTime = updateClock.Restart() / 1'000'000.f;
|
||||
|
||||
physSytem.Update(registry, 1000.f / 60.f);
|
||||
}
|
||||
|
||||
Nz::RenderFrame frame = window.AcquireFrame();
|
||||
if (!frame)
|
||||
continue;
|
||||
|
||||
renderSystem.Render(registry, frame);
|
||||
|
||||
frame.Present();
|
||||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Nz::RenderFrame frame = window.AcquireFrame();
|
||||
if (!frame)
|
||||
continue;
|
||||
|
||||
renderSystem.Render(registry, frame);
|
||||
|
||||
frame.Present();
|
||||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef NAZARA_AUDIO_ENUMS_HPP
|
||||
#define NAZARA_AUDIO_ENUMS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CORE_CLOCK_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CORE_MEMORYMANAGER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace Nz
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CORE_REFCOUNTED_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <atomic>
|
||||
|
||||
namespace Nz
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CORE_RESOURCE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
namespace Nz
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CORE_UPDATABLE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline ShaderStageTypeFlags UberShader::GetSupportedStages() const
|
||||
inline nzsl::ShaderStageTypeFlags UberShader::GetSupportedStages() const
|
||||
{
|
||||
return m_shaderStages;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue